HDU 4739 Zhuge Liang's Mines(DP)
2015-11-10 22:39
411 查看
该题一开始没想出怎么暴力, 其实我们可以先预处理出来所有的可能正方形,存到一个vector里,然后用dp的思想就行了。
因为最多只有20个点,所以我们可以状态压缩一下,然后状态转移就是d[S] = max(ans,dp(ss)+4); 如果当前这个正方形所组成的点完全在S中,那么ss就是S去掉这四个点后的状态,如此转移就可以了。
细节参见代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
using namespace std;
typedef long long ll;
const int INF = 1000000000;
const int maxn = 23;
int T,n,kase=0,len,m,d[1<<maxn], vis[1<<maxn];
struct node {
int x, y;
node(int xx=0, int yy=0):x(xx), y(yy) {}
bool operator < (const node& rhs) const {
return x < rhs.x || (x == rhs.x && y < rhs.y);
}
}a[maxn];
vector<int> g;
int dp(int S) {
if(vis[S] == kase) return d[S];
vis[S] = kase;
int& ans = d[S];
ans = 0;
for(int i=0;i<len;i++) {
int v = g[i];
if((S|v) == S) {
int ss = S ^ v;
ans = max(ans,dp(ss)+4);
}
}
return ans;
}
int main() {
while(~scanf("%d",&n)) {
if(n < 0) return 0;
g.clear();
for(int i=0;i<n;i++) scanf("%d%d",&a[i].x,&a[i].y);
sort(a,a+n);
for(int i=0;i<n;i++) {
for(int j=i+1;j<n;j++) {
if(a[i].x != a[j].x) break;
for(int ii=j+1;ii<n;ii++) {
for(int jj=ii+1;jj<n;jj++) {
if(a[ii].x != a[jj].x) break;
if(a[i].y == a[ii].y && a[j].y == a[jj].y && a[j].y-a[i].y == a[ii].x-a[i].x) {
int v = 0;
v |= (1<<i); v |= (1<<j);
v |= (1<<ii); v |= (1<<jj);
g.push_back(v);
}
}
}
}
}
len = g.size();
++kase;
printf("%d\n",dp((1<<n)-1));
}
return 0;
}
因为最多只有20个点,所以我们可以状态压缩一下,然后状态转移就是d[S] = max(ans,dp(ss)+4); 如果当前这个正方形所组成的点完全在S中,那么ss就是S去掉这四个点后的状态,如此转移就可以了。
细节参见代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
using namespace std;
typedef long long ll;
const int INF = 1000000000;
const int maxn = 23;
int T,n,kase=0,len,m,d[1<<maxn], vis[1<<maxn];
struct node {
int x, y;
node(int xx=0, int yy=0):x(xx), y(yy) {}
bool operator < (const node& rhs) const {
return x < rhs.x || (x == rhs.x && y < rhs.y);
}
}a[maxn];
vector<int> g;
int dp(int S) {
if(vis[S] == kase) return d[S];
vis[S] = kase;
int& ans = d[S];
ans = 0;
for(int i=0;i<len;i++) {
int v = g[i];
if((S|v) == S) {
int ss = S ^ v;
ans = max(ans,dp(ss)+4);
}
}
return ans;
}
int main() {
while(~scanf("%d",&n)) {
if(n < 0) return 0;
g.clear();
for(int i=0;i<n;i++) scanf("%d%d",&a[i].x,&a[i].y);
sort(a,a+n);
for(int i=0;i<n;i++) {
for(int j=i+1;j<n;j++) {
if(a[i].x != a[j].x) break;
for(int ii=j+1;ii<n;ii++) {
for(int jj=ii+1;jj<n;jj++) {
if(a[ii].x != a[jj].x) break;
if(a[i].y == a[ii].y && a[j].y == a[jj].y && a[j].y-a[i].y == a[ii].x-a[i].x) {
int v = 0;
v |= (1<<i); v |= (1<<j);
v |= (1<<ii); v |= (1<<jj);
g.push_back(v);
}
}
}
}
}
len = g.size();
++kase;
printf("%d\n",dp((1<<n)-1));
}
return 0;
}
相关文章推荐
- 基于Android中dp和px之间进行转换的实现代码
- Android中dip、dp、sp、pt和px的区别详解
- LFC1.0.0 版本发布
- Android px、dp、sp之间相互转换
- HP data protector软件学习1--基本角色与基本工作流程
- HP data protector软件学习2--软件组成与界面介绍
- android中像素单位dp、px、pt、sp的比较
- Android对px和dip进行尺寸转换的方法
- Android根据分辨率进行单位转换-(dp,sp转像素px)
- android 尺寸 dp,sp,px,dip,pt详解
- DP问题各种模型的状态转移方程
- HDU 1568
- HDU1290
- POJ-1695-Magazine Delivery-dp
- nyoj-1216-整理图书-dp
- TYVJ1193 括号序列解题报告
- 对DP的一点感想
- TYVJ上一些DP的解题报告
- HDU1568(Fobonacci公式)
- HDU ACM Step 2.2.2 Joseph(约瑟夫环问题)