您的位置:首页 > 其它

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  HDU acm-icpc dp 状态压缩