Sharing Chocolate
给你x*y巧克力,问你能不能切成n块给定面积的巧克力,每次只能沿一条方格线所在直线切且不能同时切割多块巧克力
dp[r][c][S]表示r*c切S集合面积是否可行
不难发现r*c=S集合面积的和是可行的必要条件,因此c可以通过S集合面积的和推出,状态简化为dp[r][S]
枚举S子集S0,把r*c分成r0*c或r*c0分别切S0和S-S0,转移即可
RE一直再想爆栈的事情
结果是内存报了
浪费了一个多小时
mdzz
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <queue> 7 #include <vector> 8 #define min(a, b) ((a) < (b) ? (a) : (b)) 9 #define max(a, b) ((a) > (b) ? (a) : (b)) 10 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a)) 11 inline void swap(int &a, int &b) 12 { 13 int tmp = a;a = b;b = tmp; 14 } 15 inline void read(int &x) 16 { 17 x = 0;char ch = getchar(), c = ch; 18 while(ch < '0' || ch > '9') c = ch, ch = getchar(); 19 while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar(); 20 if(c == '-') x = -x; 21 } 22 23 const int INF = 0x3f3f3f3f; 24 25 int n,x,y,a[110],dp[110][1 << 15],sum[1 << 15],ma,ans,t,b[110][1 << 16],num[1 << 15]; 26 27 int tiaoshi; 28 29 int dfs(int r, int S) 30 { 31 if(b[r][S]) return dp[r][S]; 32 b[r][S] = 1; 33 if(num[S] == 1) return dp[r][S] = 1; 34 int c = sum[S] / r; 35 for(register int SS = (S - 1) & S;SS;SS = (SS - 1) & S) 36 { 37 if(sum[SS] % r == 0 && ((sum[SS] < r) || (sum[S - SS] < r))) 38 ++ tiaoshi; 39 if(sum[SS] % r == 0 && dfs(min(r, sum[SS]/r), SS) && dfs(min(r, (sum[S - SS])/r), S - SS)) 40 return dp[r][S] = 1; 41 if(sum[S - SS]/c == 0) 42 ++ tiaoshi; 43 if(sum[SS] % c == 0 && ((sum[SS] < c) || (sum[S - SS] < c))) 44 ++ tiaoshi; 45 if(sum[SS] % c == 0 && dfs(min(c, sum[SS]/c), SS) && dfs(min(c, (sum[S - SS])/c), S - SS)) 46 return dp[r][S] = 1; 47 } 48 return dp[r][S] = 0; 49 } 50 51 int main() 52 { 53 while(scanf("%d", &n) != EOF && n) 54 { 55 ++ t; 56 read(x), read(y); 57 memset(b, 0, sizeof(b)); 58 memset(sum, 0, sizeof(sum)); 59 memset(num, 0, sizeof(num)); 60 for(register int i = 1;i <= n;++ i) read(a[i]); 61 ma = 1 << n; 62 for(register int S = 0;S < ma;++ S) 63 for(register int i = 1;i <= n;++ i) 64 { 65 if(S == 260) 66 ++ tiaoshi; 67 if(S & (1 << (i - 1))) 68 sum[S] += a[i], ++ num[S]; 69 } 70 if(sum[ma - 1] != x * y) ans = 0; 71 else ans = dfs(min(x, y), ma - 1); 72 if(ans) printf("Case %d: Yes ", t); 73 else printf("Case %d: No ", t); 74 } 75 return 0; 76 }