LA4794 Sharing Chocolate

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\n", t);
73         else printf("Case %d: No\n", t);
74     }
75     return 0;
76 }
LA4794

 

posted @ 2018-01-17 15:04  嘒彼小星  阅读(264)  评论(0编辑  收藏  举报