LA 4794 - Sharing Chocolate dp

题意

  有一块\(x*y\)的巧克力,问能否恰好分成n块,每块个数如下

输入格式

   n

   x y

   a1 a2 a3 ... an

首先\(x \times y 必然要等于 \sum\limits_{i=1}^{n}a_i\)

设集合状态为S,则转移方程为

   \(f(x,y,S)=(f(x,c_0,S_0)\&\& f(x,y-c_0,S_1))\|(f(c_0,y,S_0)\&\& f(x-c_0,y,S_1)) \) 分别对应横着掰和竖着掰

由于 \(x \times y = \sum\limits_{i=1}^{n}a_i\) 故可以简化为f(x,S) x为min(x,y)

 

LA 4794 - Sharing Chocolate  dp
 1 /*
 2 author:jxy
 3 lang:C/C++
 4 university:China,Xidian University
 5 **If you need to reprint,please indicate the source**
 6 */
 7 #include <iostream>
 8 #include <cstdio>
 9 #include <cstdlib>
10 #include <cstring>
11 #include <algorithm>
12 using namespace std;
13 int org[15];
14 int sum[1<<15],Max;
15 int f[105][1<<15],vis[105][1<<15];
16 int count_one(int x) //统计1的个数
17 {
18     x=(x&0x55555555)+(x>>1&0x55555555);
19     x=(x&0x33333333)+(x>>2&0x33333333);
20     x=(x&0x0F0F0F0F)+(x>>4&0x0F0F0F0F);
21     x=(x&0x00FF00FF)+(x>>8&0x00FF00FF);
22     x=(x&0x0000FFFF)+(x>>16&0x0000FFFF);
23     return x;
24 }
25 int dp(int x,int S) 
26 {
27     if(vis[x][S])return f[x][S]; //记忆化搜索
28     vis[x][S]=1;
29     int &ans=f[x][S],S1,y=sum[S]/x;
30     ans=0;
31     if(count_one(S)==1)return ans=1;
32     for(int S0=(S-1)&S;S0;S0=(S0-1)&S)
33     {
34         S1=S-S0;
35         if(sum[S0]%x==0&&dp(min(x,sum[S0]/x),S0)&&dp(min(x,sum[S1]/x),S1)) //横着掰
36             return ans=1;
37         if(sum[S0]%y==0&&dp(min(y,sum[S0]/y),S0)&&dp(min(y,sum[S1]/y),S1)) //竖着掰
38             return ans=1;
39     }
40     return ans;
41 }
42 int main()
43 {
44     int n,i;
45     int x,y,C=0;
46     while(~scanf("%d",&n)&&n)
47     {
48         scanf("%d%d",&x,&y);
49         for(i=0;i<n;i++)
50             scanf("%d",&org[i]);
51         memset(vis,0,sizeof(vis));
52         Max=(1<<n)-1;
53         int S;
54         for(S=1;S<=Max;S++)//记录每一个状态对应的巧克力块和
55         {
56             sum[S]=0;
57             for(i=0;i<n;i++)
58                 if(S&(1<<i))sum[S]+=org[i];
59         }
60         int ans=0;
61         if(sum[Max]==x*y)ans=dp(min(x,y),Max);
62         printf("Case %d: %s\n",++C,ans?"Yes":"No");
63     }
64 }
LA 4794 - Sharing Chocolate  dp

LA 4794 - Sharing Chocolate dp

上一篇:servlet同一用户的不同页面共享数据


下一篇:Scene View Navigation