多重背包(标准模板)

#include<iostream>
#include<cstdio>
using namespace std;
#define MAX(a,b) (a>b)?a:b
const int SIZE=1000+16;
int nKind; //物品种类数目
int nLimit; //背包容量
int val[SIZE]; //每种背包的价值
int weight[SIZE]; //每种背包的重量
int bag[SIZE]; //每种背包的数目
int dp[SIZE];  

//0-1背包, 代价为cost, 获得的价值为value 
void ZeroOnePack(int cost, int value)
{
    for(int i=nLimit; i>=cost; i--)    //逆序 
    {
        dp[i]=MAX(dp[i], dp[i-cost]+value);
    }
}

//完全背包, 代价为cost, 获得的价值为value
void CompletePack(int cost, int value) 
{
    for(int i=cost; i<=nLimit; i++)    //顺序 
    {
        dp[i]=MAX(dp[i],dp[i-cost]+value);
    }
}

//多重背包 代价为cost, 获得的价值为value, 该种背包的数目为amount 
void MultiplePack(int cost, int value, int amount)
{
    if(cost*amount>=nLimit) CompletePack(cost, value);
    else
    {
        int k=1;
        while(k<amount)
        {
            ZeroOnePack(k*cost, k*value);
            amount-=k;
            k<<=1;
        }
        
        ZeroOnePack(amount*cost, amount*value);
    }
}
int main()
{
    //不要求装满则dp中的元素均为零;    
    //否则dp[0]=0.其他为 -INF 
    memset(dp,0,sizeof(dp));
    
    scanf("%d %d",&nKind,&nLimit);
    
    for(int i=0;i<nKind;i++)
    {
        scanf("%d %d %d",&weight[i],&val[i],&bag[i]);
    }
    
    for(int i=0; i<nKind; i++)
        MultiplePack(weight[i],val[i],bag[i]);
    
    printf("%d
",dp[nLimit]);
    
    return 0;
}
原文地址:https://www.cnblogs.com/program-ccc/p/4704830.html