您的位置:首页 > 其它

uvalive4794(集合+状态压缩)

2015-02-13 13:41 309 查看
题意:

有一块x*y的巧克力,每次可以切一刀,问切若干刀后(不能两块同时切),可不可以切成n块,面积分别是a1,a2...an;的巧克力:

思路:

看到final的题就怂了;

最后还是参考了大白,还有网上的题解:
http://www.cnblogs.com/hlmark/p/4059654.html
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int N = 16;
const int M = 100 + 10;
int n, part
, sum[1<<N], f[1<<N][M], vis[1<<N][M];
int bitcount(int x) {
return x == 0 ? 0 : bitcount(x / 2) + (x & 1);
}
int dp(int sta, int x) {
if(vis[sta][x])
return f[sta][x];
vis[sta][x] = 1;
int& ans = f[sta][x];
if(bitcount(sta) == 1) return ans = 1;
int y = sum[sta] / x;
for(int sta0 = (sta - 1) & sta; sta0 != 0; sta0 = (sta0 - 1) & sta) {
int sta1 = sta-sta0;
if(sum[sta0] % x == 0 && dp(sta0, min(x, sum[sta0] / x)) && dp(sta1, min(x, sum[sta1] / x)))
return ans = 1;
if(sum[sta0] % y == 0 && dp(sta0, min(y, sum[sta0] / y)) && dp(sta1, min(y, sum[sta1] / y)))
return ans = 1;
}
return ans = 0;
}
int main() {
int cas = 0, n, x, y;
while(scanf("%d", &n) && n) {
scanf("%d%d", &x, &y);
for(int i = 0; i < n; i++)
scanf("%d", &part[i]);
memset(sum, 0, sizeof(sum));
for(int i = 0; i < (1<<n); i++)
for(int j = 0; j < n; j++)
if(i & (1 << j))
sum[i] += part[j];
memset(vis, 0, sizeof(vis));
int ans;
if(sum[(1 << n) - 1] != x*y || sum[(1 << n) - 1] % x != 0)
ans = 0;
else
ans = dp((1 << n) - 1, min(x,y));
printf("Case %d: %s\n", ++cas, ans ? "Yes" : "No");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: