SDUTOJ 3131 A回(多重背包)

题目描述

新年伊始,我飞瞅准机会要大赚一笔,于是我飞换了一个体积为V的背包。

 

现在有N种商品,每种商品有Mi件,可以带来的收益为Pi,体积为Vi

那么问题来了,在所装物品不超过V的前提下的最大收益是多少?

谁能快速的做帮我飞算出来,我飞就让谁出任UFO,迎娶高富帅,走上人生巅峰233。各位准Final巨巨加油啊。

输入

  第一行输入一个 T ,代表有 T(1 <= T <= 15) 组数据。

对于每一组数据:

第一行有两个整数N , V

接下里的N行,每行三个整数MiViPi

对于所有数据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;
}



你可能感兴趣的:(背包)