51NOD-1086 背包问题 V2(多重背包)

xiaoxiao2021-02-28  21

1086 背包问题 V2  基准时间限制:1 秒 空间限制:131072 KB 分值: 40  难度:4级算法题  收藏  关注 有N种物品,每种物品的数量为C1,C2......Cn。从中任选若干件放在容量为W的背包里,每种物品的体积为W1,W2......Wn(Wi为整数),与之相对应的价值为P1,P2......Pn(Pi为整数)。求背包能够容纳的最大价值。 Input 第1行,2个整数,N和W中间用空格隔开。N为物品的种类,W为背包的容量。(1 <= N <= 100,1 <= W <= 50000) 第2 - N + 1行,每行3个整数,Wi,Pi和Ci分别是物品体积、价值和数量。(1 <= Wi, Pi <= 10000, 1 <= Ci <= 200) Output 输出可以容纳的最大价值。 Input示例 3 6 2 2 5 3 3 8 1 4 1 Output示例 9 这是一个多重背包问题,对于每一个数量为ci的物品要是不用合并直接当ci个物品 用完全背包的解法去解,结果肯定是超时的,所以就要用二进制去优化,那怎么用 二进制进行优化呢? 将数量为ci个物品拆分为n个物品,每个物品分别是原来物品体积和价值的2^0 ,2^1,2^2...2^k,ci-2^(k+1)+1倍。 例如当ci为14时,拆分的分别为 1,2,4,7。 那为什么要这样做呢? 因为一个物品要么全部放进背包里要不部分放进去要不就不放进去,那么 就只需要 考虑部分的时候就行了,其他的不用考虑,当需要部分物品时则 能用这几个数的一 部分相加得到。下面是代码部分。 #include<iostream> #include<cstdio> using namespace std; int dp[50010],w[10010],p[10010];//w和p分别表示新组成的物品的体积和价值 int main() { int N,W,n=1;//n表示新组成的物品个数 scanf("%d%d",&N,&W); for(int i=1;i<=N;i++){ int wi,pi,ci; scanf("%d%d%d",&wi,&pi,&ci); int j; for(j=1;j<ci;j=j<<1){ w[n]=wi*j; p[n]=pi*j; ci-=j; n++; } w[n]=wi*ci; p[n]=pi*ci; n++; } for(int i=1;i<=n;i++)//接下来就是一个完全背包的问题了 for(int j=W;j>=w[i];j--) dp[j]=max(dp[j],dp[j-w[i]]+p[i]); printf("%d\n",dp[W]); return 0; }
转载请注明原文地址: https://www.6miu.com/read-2625857.html

最新回复(0)