hdu 4778

知道是状态压缩,但是不会做;

看题解学的;

dp[i]表示现在状态是i,先手-后手的分数。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 
 6 int b,g,n,s,a,co[20],dd[20];
 7 int map[25][20],dp[1<<21];
 8 
 9 int main()
10 {
11     while(scanf("%d%d%d",&g,&b,&s)&&(b+g+s))
12     {
13         memset(map,0,sizeof map);
14         for(int i=0; i<b; i++)
15         {
16             scanf("%d",&n);
17             while(n--)
18             {
19                 scanf("%d",&a);
20                 map[i][a]++;
21             }
22         }
23         dp[0]=0;
24         int tot=1<<b;
25         for(int i=1; i<tot; i++)
26         {
27             dp[i]=-99999999;
28             for(int j=1; j<=g; j++)co[j]=0;
29             for(int j=0; j<b; j++)
30             {
31                 if((i&(1<<j))==0)
32                 {
33                     for(int k=1; k<=g; k++)
34                     {
35                         co[k]+=map[j][k];
36                         co[k]%=s;
37                     }
38                 }
39             }
40             for(int j=0; j<b; j++)
41             {
42                 if((i&(1<<j)))
43                 {
44                     int cnt=0;
45                     for(int k=1; k<=g; k++)dd[k]=co[k];
46                     for(int k=1; k<=g; k++)
47                     {
48                         dd[k]+=map[j][k];
49                         cnt+=dd[k]/s;
50                         dd[k]%=s;
51                     }
52                 if(cnt>0)dp[i]=max(dp[i],cnt+dp[i^(1<<j)]);
53                 else dp[i]=max(dp[i],-dp[i^(1<<j)]);
54                 }
55             }
56         }
57         printf("%d\n",dp[tot-1]);
58     }
59     return 0;
60 }
View Code

 

posted @ 2013-11-12 20:41  Yours1103  阅读(222)  评论(0编辑  收藏  举报