nyoj546Divideing Jewels(多重背包)

题目链接:click here~

多重背包:特点;每种物品有有限件可用,转化为01背包来处理,用到了二进制优化,例如13可以分成1,2,4,6,因为这四个数字的和可以组成1-13的所有数字。

代码如下:

01. #include<stdio.h>
02. #include<string.h>
03. #define max(a,b)a>b?a:b
04. int dp[50010],v;
05. void bag(int c,int w)
06. {
07. for(int i=v;i>=c;i--)
08. {
09. dp[i]=max(dp[i],dp[i-c]+w);
10. }
11. }
12. int main()
13. {
14. int a[13],count=1;
15. while(1)
16. {
17. int sum=0;
18. for(int i=1;i<=10;i++)
19. {
20. scanf("%d",&a[i]);
21. sum+=a[i]*i;
22. }
23. if(sum==0)
24. break;
25. if(sum%2)
26. printf("#%d:Can't be divided.\n\n",count++);
27. else
28. {
29. v=sum/2;
30. memset(dp,0,sizeof(dp));
31. for(int i=1;i<=10;i++)
32. {
33. int p=a[i];
34. int q=1;
35. while(q<p)
36. {
37. bag(i*q,i*q);
38. p-=q;
39. q*=2;
40. }
41. if(p)
42. {
43. bag(i*p,i*p);
44. }
45. }
46. if(dp[v]==v)
47. printf("#%d:Can be divided.\n\n",count++);
48. else
49. printf("#%d:Can't be divided.\n\n",count++);
50. }
51. }
52. return 0;
53. }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值