题目描述
新年伊始,我飞瞅准机会要大赚一笔,于是我飞换了一个体积为V的背包。
现在有N种商品,每种商品有Mi件,可以带来的收益为Pi,体积为Vi。
那么问题来了,在所装物品不超过V的前提下的最大收益是多少?
谁能快速的做帮我飞算出来,我飞就让谁出任UFO,迎娶高富帅,走上人生巅峰233。各位准Final巨巨加油啊。
输入
第一行输入一个
T
,代表有
T(1 <= T <= 15)
组数据。
对于每一组数据:
第一行有两个整数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<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#define LL long long
#define inf 0x3f3f3f3f
using namespace std;
int p[100010],num[100010],vi[100010];
int dp[160010],v;
void zeroonepack(int p1,int v1)
{
for(int i=v; i>=v1; i--)
dp[i]=max(dp[i],dp[i-v1]+p1);
}
void complatepack(int p1,int v1)
{
for(int i=v1; i<=v; i++)
dp[i]=max(dp[i],dp[i-v1]+p1);
}
void multiplepack(int nu,int p1,int v1)
{
if(v<=nu*v1)
{
complatepack(p1,v1);
return ;
}
else
{
int tmp=1;
while(tmp<=nu)
{
zeroonepack(tmp*p1,tmp*v1);
nu-=tmp;
tmp<<=1;
}
zeroonepack(nu*p1,nu*v1);
}
}
int main()
{
int n,m,x,k,i,cla;
scanf("%d",&cla);
while(cla--)
{
memset(dp,0,sizeof(dp));
scanf("%d%d",&n,&v);
for(i=0; i<n; i++)
{
scanf("%d%d%d",&num[i],&vi[i],&p[i]);
}
for(i=0; i<n; i++)
{
multiplepack(num[i],p[i],vi[i]);
}
printf("%d\n",dp[v]);
}
return 0;
}