hdu-1059 Dividing---多重背包

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=1059

题目大意:

就是有价值1、2、3、4、5、6的硬币各多少个,然后让你判断能否把他们分成价值相等的两部分。

思路:

多重背包的模板

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 using namespace std;
 5 const int INF = 0x3f3f3f3f;
 6 const int maxn = 200000 + 10;
 7 int n, m, cases;
 8 int dp[maxn];
 9 int sum;
10 
11 void ZeroOnePack(int cost, int value)
12 {
13     for(int v = sum; v >= cost; v--)//01背包正序
14         dp[v] = max(dp[v], dp[v - cost] + value);
15 }
16 
17 void CompletePack(int cost, int value)
18 {
19     for(int v = cost; v <= sum; v++)
20         dp[v] = max(dp[v], dp[v - cost] + value);
21 }
22 void MutiplePack(int cost, int value, int amount)
23 {
24     if(cost * amount >= sum)//超过总体积,进行完全背包
25         CompletePack(cost, value);
26     else
27     {
28         int k = 1;//二进制优化
29         while(k <= amount)
30         {
31             ZeroOnePack(k * cost, k * value);
32             amount -= k;
33             k *= 2;
34         }
35         ZeroOnePack(amount * cost, amount * value);
36     }
37 }
38 int main()
39 {
40     int a[10];
41     while(cin >> a[1] >> a[2] >> a[3] >> a[4] >> a[5] >> a[6])
42     {
43         //if(a[1] + a[2] + a[3] + a[4] + a[5] + a[6] == 0)break;
44         if(!a[1]&&!a[2]&&!a[3]&&!a[4]&&!a[5]&&!a[6])break;
45         sum = 0;
46         for(int i = 1; i <= 6; i++)sum += i * a[i];
47         printf("Collection #%d:\n",++cases);
48         if(sum & 1)//总和为奇数,一定不能均分
49         {
50             printf("Can't be divided.\n\n");
51             continue;
52         }
53         memset(dp, 0, sizeof(dp));
54         sum /= 2;
55         for(int i = 1; i <= 6; i++)
56             MutiplePack(i, i, a[i]);//多重背包
57         if(dp[sum] == sum)
58             printf("Can be divided.\n\n");
59         else printf("Can't be divided.\n\n");
60     }
61     return 0;
62 }

 

转载于:https://www.cnblogs.com/fzl194/p/8831576.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值