首页 > 代码库 > hdu 1059 Dividing (多重背包)
hdu 1059 Dividing (多重背包)
题目大意:有6件物品,第一件物品的价值为1,第二件物品的件值为2......以此类推。测试数据给出的是每一件物品的数量。平均分给两个人,是两个人得到的物品价值相等,但是单个物品是无法再分的。
思路:因为给的每一件物品的数量是有限个由此可以想到用多重背包(当然也可以用搜索,但是所有的物品的总价值为20000,每个分支至少有20000/6约等于3000多个,肯定会超时)
(1)先判断总的价值是否能够被2整除,如果不能整除则物品不能够被平分(因为单个物品是最小的单位是不能够再分的)
(2)判断现有的物品是否能够装满总价值的一半,如果总价值的一半可以拼凑出来则另外的一半物品是一定可以拼凑出来的,这样得到的物品就是可以平分的。因为物品的数量是有限的,用到了多重背包。
#include <iostream> using namespace std; #define MAX 50000 int c[7], v[7], tot, mid; int dp[MAX]; #define max(a, b) ((a) > (b) ? (a) : (b)) void comprletePack(int weitht, int value) { int i; for (i=weitht; i<=mid; i++) { dp[i] = max(dp[i], dp[i-weitht]+value); } } void onezeroPack(int weight, int value) { int i; for (i=mid; i>=weight; i--) { dp[i] = max(dp[i], dp[i-weight]+value); } } int main() { int i, cnt; for (i=1; i<7; i++) v[i] = i; cnt = 0; while (cin>>c[1]>>c[2]>>c[3]>>c[4]>>c[5]>>c[6] && (c[1]||c[2]||c[3]||c[4]||c[5]||c[6])) { cnt++; memset(dp, 0, sizeof(dp)); cout<<"Collection #"<<cnt<<":"<<endl; tot = 0; for (i=1; i<7; i++) { tot += v[i] * c[i]; } if (tot%2!=0) { cout<<"Can't be divided."<<endl; continue; } else { mid = tot / 2; for (i=1; i<7; i++) if (c[i]>0) { if (c[i]*v[i]>=mid) { comprletePack(v[i], v[i]); continue; } int k=1; while (k<c[i]) { onezeroPack(v[i]*k, v[i]*k); c[i] -= k; k <<= 1; } onezeroPack(v[i]*c[i], v[i]*c[i]); } if (dp[mid]==mid) cout<<"Can be divided.\n"<<endl; else cout<<"Can't be divided.\n"<<endl; } } return 0; }
hdu 1059 Dividing (多重背包)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。