Sharing Chocolate - UVa 1099 状压dp

Chocolate in its many forms is enjoyed by millions of people around the world every day. It is a truly universal candy available in virtually every country around the world.

You find that the only thing better than eating chocolate is to share it with friends. Unfortunately your friends are very picky and have different appetites: some would like more and others less of the chocolate that you offer them. You have found it increasingly difficult to determine whether their demands can be met. It is time to writte a program that solves the problem once and for all!

Your chocolate comes as a rectangular bar. The bar consists of
same-sized rectangular pieces. To share the chocolate you may break one
bar into two pieces along a division between rows or columns of the bar.
You or the may then repeatedly break the resulting
pieces in the same manner. Each of your friends insists on a getting a
single rectangular portion of the chocolate that has a specified number
of pieces. You are a little bit insistent as well: you will break up
your bar only if all of it can be distributed
to your friends, with none left over.

For exampla, Figure 9 shows one way that a chocolate bar consisting of 3 x 4 pieces
can be split into 4 parts that contain 6, 3, 2, and 1 pieces
respectively, by breanking it 3 times (This corresponds to the first
sample input.)

Input

The input consists of
multiple test cases each describing a chocolate bar to share. Each
description starts with a line containing a single integer n (1n15),
the number of parts in which the bar is supposed to be split. This is followed by a line containing two integers x and y (1xy100),
the dimensions of the chocolate bar. The next line contains n positive integers, giving the number of pieces that are supposed
to be in each of the n parts.

The input is terminated by a line containing the integer zero.

Output

For each test case, first
display its case number. Then display whether it is possible to break
the chocolate in the desired way: display ``Yes" if it is possible, and ``No" otherwise. Follow the
format of the sample output.

Sample Input

4
3 4
6 3 2 1
2
2 3
1 5
0

Sample Output

Case 1: Yes
Case 2: No

题意:问x*y的巧克力能否分成给定的n块大小。

思路:dp[c][S]表示状压状态为S的巧克力能否以c为短边组成矩形,然后dfs。

AC代码如下:

[cpp] view plaincopy

    1. #include<cstdio>
    2. #include<cstring>
    3. #include<algorithm>
    4. using namespace std;
    5. int sum[100010],num[20],vis[110][100010],dp[110][100010],pow2[20];
    6. int n,t;
    7. int dfs(int c,int S)
    8. {
    9. if(vis[c][S]==t)
    10. return dp[c][S];
    11. int i,j,k,l,ans=0,S1,S2;
    12. vis[c][S]=t;
    13. for(j=0;j<n;j++)
    14. if(S==pow2[j])
    15. return dp[c][S]=1;
    16. l=sum[S]/c;
    17. for(S1=(S-1)&S;S1>0;S1=(S1-1)&S)
    18. {
    19. S2=S-S1;
    20. if(sum[S1]%c==0 && dfs(min(c,sum[S1]/c),S1) && dfs(min(c,sum[S2]/c),S2))
    21. return dp[c][S]=1;
    22. if(sum[S1]%l==0 && dfs(min(l,sum[S1]/l),S1) && dfs(min(l,sum[S2]/l),S2))
    23. return dp[c][S]=1;
    24. }
    25. return dp[c][S]=0;
    26. }
    27. int main()
    28. {
    29. int i,j,k,c,l,S,ans;
    30. pow2[0]=1;
    31. for(i=1;i<=20;i++)
    32. pow2[i]=pow2[i-1]*2;
    33. while(~scanf("%d",&n) && n>0)
    34. {
    35. t++;
    36. scanf("%d%d",&c,&l);
    37. for(i=0;i<n;i++)
    38. scanf("%d",&num[i]);
    39. S=pow2[n]-1;
    40. for(i=1;i<=S;i++)
    41. {
    42. sum[i]=0;
    43. for(j=0;j<n;j++)
    44. if(i&pow2[j])
    45. sum[i]+=num[j];
    46. }
    47. if(c*l!=sum[S])
    48. ans=0;
    49. else
    50. ans=dfs(min(c,l),S);
    51. printf("Case %d: ",t);
    52. if(ans)
    53. printf("Yes\n");
    54. else
    55. printf("No\n");
    56. }
    57. }
时间: 2024-11-04 21:55:47

Sharing Chocolate - UVa 1099 状压dp的相关文章

UVa 10817 (状压DP + 记忆化搜索) Headmaster&#39;s Headache

题意: 一共有s(s ≤ 8)门课程,有m个在职教师,n个求职教师. 每个教师有各自的工资要求,还有他能教授的课程,可以是一门或者多门. 要求在职教师不能辞退,问如何录用应聘者,才能使得每门课只少有两个老师教而且使得总工资最少. 分析: 因为s很小,所以可以用状态压缩. dp(i, s1, s2)表示考虑了前i个人,有一个人教的课程的集合为s1,至少有两个人教的集合为s2. 在递归的过程中,还有个参数s0,表示还没有人教的科目的集合. 其中m0, m1, s0, s1, s2的计算用到位运算,还

UVa 11825 (状压DP) Hackers&#39; Crackdown

这是我做状压DP的第一道题,状压里面都是用位运算来完成的,只要耐下心来弄明白每次位运算的含义,还是容易理解的. 题意: 有编号为0~n-1的n台服务器,每台都运行着n中服务,每台服务器还和若干台其他服务器相连.对于每台服务器,你可以选择停止该台以及与这台服务器相连的服务器的一项服务.如果一台服务器的所有服务都被停止,则这台服务器瘫痪.问最多能使多少台服务器瘫痪 转化为数学模型(题目是如何抽象成这种数学模型的也要好好想想): 把n个集合尽可能多的分成若干组,使得每组所有集合的并集为全集.这里集合P

UVa 132 Another Chocolate Maniac(状压DP)

132. Another Chocolate Maniac time limit per test: 0.25 sec. memory limit per test: 4096 KB Bob really LOVES chocolate. He thinks he never gets enough. Imagine his joy when his parents told him that they would buy him many rectangular chocolate piece

UVa 1252 (状压DP + 记忆化搜索) Twenty Questions

题意: 有n个长为m的各不相同的二进制数(允许存在前导0),别人已经事先想好n个数中的一个数W,你要猜出这个数. 每次只可以询问该数的第K为是否为1. 问采用最优询问策略,则最少需要询问多少次能保证猜到. 比如有1100 和 0110两个数,只需要询问第一或第三位数是否为1,即可猜中,因此答案为1. 分析: d(s, a)表示已经询问了的集合s,在已经询问了的集合中W中为1的集合为a,还需要询问多少次. 如果下一次询问第k位,则询问次数为: 然后取所有k里的最小值即可. 预处理: 对于每个s和a

UVA - 1412 状压dp九进制表示状态

此题难点在于用九进制表示状态,并且转移 这里九进制用vector表示,再用map作为此状态特有的标记 此处用刷表法,每一种状态转移都经历一遍,最终状态就是正确答案,注意界限 #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<map> #include<stack> #include<queue> #include&

UVA - 11825 状压DP

该题目是EMAXX推荐的练习题,刘汝佳的书也有解说 如果S0属于全集,那S0就可以作为一个分组,那么S分组数可以是best{当前S中S0的补集+1} 对于集合类的题目我觉得有点抽象,希望多做多理解把 #include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<

UVa 12235 状压DP Help Bubu

题解戳这 一开始没看懂题解,后来想明白以后,d(i, j, s, x)是考虑第i本书的时候,前面已经拿走了j本书,剩下的书的种类的二进制状态为s,剩下的最后一本书的编号为x,所能得到的最小混乱度. 这里状态定义的时候,先不考虑把拿出来的书放回去. 最后统计答案的时候,把那些拿出来的书再加上. all是所有n本书的状态,s是剩下书的种类的状态. 如果拿出来的书中有和前面高度相同的,直接插到相邻的位置就行了,不会增加混乱度. 如果拿出来的书中没有和前面高度相同的,不管放在那里混乱度都会加1,这样所增

(状压dp)uva 10817 Headmaster&#39;s Headache

题目地址 1 #include <bits/stdc++.h> 2 typedef long long ll; 3 using namespace std; 4 const int MAX=1e5+5; 5 const int INF=1e9; 6 int s,m,n; 7 int cost[125]; 8 //char sta[MAX]; 9 string sta; 10 int able[125]; 11 int dp[125][1<<8][1<<8]; 12 in

UVA 10817 Headmaster&#39;s Headache 状压DP

记录两个状态S1,S2分别记录哪些课程被1个人教过或2个人教过,然后记忆化搜索 UVA - 10817 Headmaster's Headache Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu Submit Status Description Problem D: Headmaster's Headache Time limit: 2 seconds The headmaster of Spr