多重背包

模板

#include<bits/stdc++.h>
using namespace std;
const int maxn=100005;
int c[maxn],value[maxn],num[maxn];//cost:费用, val:价值, num:数量
int dp[maxn];           
int V;
//01背包
void ZeroOnePack(int cost,int val){//费用、价值
	for(int i=V;i>=cost;i--)//V表示背包最大的容量
		dp[i]=max(dp[i],dp[i-cost] + val);
	return ;
}
//完全背包
void CompletePack(int cost,int val){
	for(int i=cost;i<=V;i++)
		dp[i]=max(dp[i],dp[i-cost]+val);
	return ;
}
//多重背包(别问我为什么知道这么多英文)
void MultiplePack(int cost, int val, int tot){//费用、价值、数量
	if(cost * tot >= V) //如果物品数量足够多,就是完全背包 
		CompletePack(cost, val); //完全背包 
	else{
		int k=1; //k表示2的几次方 
		while(k<tot){
			ZeroOnePack(k * cost, k * val);
			tot=tot-k; //更新当前物品的数量 
			k=k*2; //倍增 
		}
		ZeroOnePack(tot*cost,tot*val);
	}
	return ;
}
int main(){
	int n;
	cin>>n>>V; //背包容量为V, 物品n种 
	for(int i=1;i<=n;i++) //n种物品 
		cin>>c[i]>>value[i]>>num[i]; //费用、价值、数量 
	for(int i=1;i<=n;i++) //前i种物品 
		MultiplePack(c[i], value[i], num[i]); //多重背包函数计算dp 
	cout<<dp[V]<<endl;
	return 0;
}
posted @ 2019-07-19 17:37  xzj213  阅读(148)  评论(0编辑  收藏  举报