标签:
新年伊始,我飞瞅准机会要大赚一笔,于是我飞换了一个体积为V的背包。
现在有N种商品,每种商品有Mi件,可以带来的收益为Pi,体积为Vi。
那么问题来了,在所装物品不超过V的前提下的最大收益是多少?
谁能快速的做帮我飞算出来,我飞就让谁出任UFO,迎娶高富帅,走上人生巅峰233。各位准Final巨巨加油啊。
对于每一组数据:
第一行有两个整数N , V。
接下里的N行,每行三个整数Mi,Vi,Pi。
对于所有数据1 <= N <= 200,1 <= V <= 15000,1 <= Mi , Vi, Pi <= 100000。
1 2 10 1 10 10 2 6 21
21
#include <stdio.h> #include <math.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <algorithm> #include <set> #include <queue> #include <stack> #include <map> using namespace std; long long dp[15010];//dp与V有关,p,w与n有关 long long w[100010],p[100010],k[100010];//w价值,p费用,k数量 int n,V; void ZeroOnePack(int p,int w)//01背包(该种物品只有1个) { for(int i=V; i>=p; i--) { dp[i] = max(dp[i],dp[i-p]+w); } } void CompletePack(int p,int w)//完全背包(该种物品不限量) { for(int i=p; i<=V; i++) { dp[i] = max(dp[i],dp[i-p]+w); } } void MultiplePack(int p,int w,int k)//多重背包,二进制(该种物品指定上限) { if(p*k>=V) {//该种物品足以塞满背包-->转化为完全背包 CompletePack(p,w); return ; } /*二进制思想拆分:多重背包中的一个物品--变成-->0-1背包中的多个物品 容量:2^0 2^1 2^2 2^k m-∑前面 ***保证k达到最大值 价值:2^0*c 2^1*c 2^2*c 2^k*c (m-∑前面 )*c */ else { int kk= 1; while(kk<=k) { ZeroOnePack(kk*p,kk*w); k = k - kk; kk = kk<<1; } ZeroOnePack(k*p,k*w); } } int main() { int T,i,j; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&V);//n物品种数 memset(dp,0,sizeof(dp)); for(i=1; i<=n; i++) { scanf("%lld %lld %lld",&k[i],&p[i],&w[i]); } for(i=1; i<=n; i++) { MultiplePack(p[i],w[i],k[i]); } printf("%lld\n",dp[V]); } return 0; }
标签:
原文地址:http://blog.csdn.net/u013486414/article/details/44200861