hdu 4739 Zhuge Liang's Mines 2013 ACM/ICPC Asia Regional Hangzhou Online

比赛的时候跟学长说了一下我的想法,贪心,首先排序,x从小到大排序,x相同的y从小到大,然后优先选择边长小的能组成正方形的点。

但是写跪了,后来交给学长写状态压缩dp。今天看到结题报告里有人用的类似的方法过了,查看后发现是我没有判断重点的情况,改后怒ac,

还是太弱了,不然可以省下点时间做其他的题目。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #define maxlen 30
 6 using namespace std;
 7 int maps[110][110];
 8 struct node
 9 {
10     int x,y;
11 }p[maxlen];
12 int n;
13 bool cmp(node a,node b)
14 {
15     if(a.x==b.x)
16         return a.y<b.y;
17     else
18         return a.x<b.x;
19 }
20 bool judge(int x,int y)
21 {
22     return x>=0&&x<=100&&y>=0&&y<=100;
23 }
24 int main ()
25 {
26     while(scanf("%d",&n)!=EOF)
27     {
28         if(n==-1)
29             break;
30         memset(maps,0,sizeof(maps));
31         for(int i=0;i<n;++i)
32         {
33             scanf("%d%d",&p[i].x,&p[i].y);
34             maps[p[i].x][p[i].y]++;
35         }
36         sort(p,p+n,cmp);
37         int ans=0;
38         for(int i=0;i<n;++i)
39         {
40             for(int j=-100;j<=100;++j)
41             {
42                 if(j!=0&&judge(p[i].x+j,p[i].y+j)&&judge(p[i].x,p[i].y+j)&&judge(p[i].x+j,p[i].y))
43                 if(maps[p[i].x+j][p[i].y+j]&&maps[p[i].x][p[i].y+j]&&maps[p[i].x+j][p[i].y]&&maps[p[i].x][p[i].y])
44                 {
45                     maps[p[i].x+j][p[i].y+j]--;maps[p[i].x][p[i].y+j]--;maps[p[i].x+j][p[i].y]--;maps[p[i].x][p[i].y]--;
46                     ans+=4;
47                 }
48             }
49         }
50         printf("%d
",ans);
51     }
52 }
View Code

 正解是状态压缩,其实也是十分简单,一共就20个点,转化为二进制后即可以用一个整数表示整个状态。

dp[s]表示s这个状态下最多的正方形数。状态的转移也很简单。

dp[s]=max(dp[s],dp[s']+1)

如果可以组成正方形即可转到另一个状态。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include  <algorithm>
 5 #define maxlen  1<<21
 6 using namespace std;
 7 int n;
 8 int dp[maxlen];
 9 int used[30];
10 struct node
11 {
12     int x,y;
13 }p[30];
14 bool cmp(node a,node b)
15 {
16     return a.x==b.x?a.y<b.y:a.x<b.x;
17 }
18 bool judge(node a,node b,node c,node d)
19 {
20     return (a.x==b.x&&a.y==c.y&&c.x==d.x&&b.y==d.y&&b.y-a.y==c.x-a.x);
21 }
22 int dfs(int s)
23 {
24     if(s<0)
25         return 0;
26     if(dp[s])
27         return dp[s];
28     for(int i=0;i<n;++i)
29     {
30         for(int j=i+1;j<n;++j)
31         {
32             for(int k=j+1;k<n;++k)
33             {
34                 for(int l=k+1;l<n;++l)
35                 {
36                     if(judge(p[i],p[j],p[k],p[l])&&!used[i]&&!used[j]&&!used[k]&&!used[l])
37                     {
38                         used[i]=used[j]=used[k]=used[l]=true;
39                         int x = s-(1<<i)-(i<<j)-(1<<k)-(1<<l);
40                         dp[s] = max(dp[s],1+dfs(x));
41                         used[i]=used[j]=used[k]=used[l]=false;
42                     }
43                 }
44             }
45         }
46     }
47     return dp[s];
48 }
49 int main ()
50 {
51     while(scanf("%d",&n)!=EOF)
52     {
53         if(n==-1)
54             break;
55         for(int i=0;i<n;++i)
56             scanf("%d%d",&p[i].x,&p[i].y);
57         sort(p,p+n,cmp);
58         memset(dp,0,sizeof(dp));
59         memset(used,0,sizeof(used));
60         int ans = dfs((1<<n)-1);
61         printf("%d
",4*ans);
62     }
63 }
View Code
原文地址:https://www.cnblogs.com/shuzy/p/3328420.html