南沙C++信奧賽陳老師解一本通題 1270:【例9.14】混合揹包

南沙区信奥赛陈老师發表於2024-10-04

【題目描述】

一個旅行者有一個最多能裝V公斤的揹包,現在有n件物品,它們的重量分別是W1,W2,...,Wn,它們的價值分別為C1,C2,...,Cn。有的物品只可以取一次(01揹包),有的物品可以取無限次(完全揹包),有的物品可以取的次數有一個上限(多重揹包)。求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大。

【輸入】

第一行:二個整數,M(揹包容量,M<=200),N(物品數量,N<=30);

第2..N+1行:每行三個整數Wi,Ci,Pi,前兩個整數分別表示每個物品的重量,價值,第三個整數若為0,則說明此物品可以購買無數件,若為其他數字,則為此物品可購買的最多件數(Pi)。

【輸出】

僅一行,一個數,表示最大總價值。

【輸入樣例】

10  3
2  1  0
3  3  1
4  5  4

【輸出樣例】

11

【提示】

選第一件物品1件和第三件物品2件。

#include <iostream>
using namespace std;
int dp[6001][201];
int w[6001],v[6001], t[6001];//t表示揹包的型別 0代表0-1揹包 1=完全揹包 
int main()
{
	int m,n,k=0;
	cin>>m>>n;
	for(int i=1;i<=n;i++)
	{
		int wi,vi,pi;
		cin>>wi>>vi>>pi;
		if(pi==0)
		{
			k++;
			w[k]=wi;
			v[k]=vi;
			t[k]=1;//表全揹包 
		
		}
		else		//將多重揹包轉為0-1揹包 
		{
			for(int j=1;j<=pi;j++)
			{
				k++;
				w[k]=wi;
				v[k]=vi;	
			}//for
		}//else
	}
	for(int i=1;i<=k;i++)	//此時為K件物品,不是n件了 
	{
		for(int j=1;j<=m;j++)	//容量 
		{
			if(w[i]>j)
				dp[i][j]=dp[i-1][j];
			else
			{
				int put=0;
				if(t[i]==0)	//0-1揹包
					put=v[i]+dp[i-1][ j-w[i] ];
				else		//完全揹包 
					put=v[i]+dp[i][ j-w[i] ];
				int noput=dp[i-1][j];
				dp[i][j]=max(put,noput); 
			}
		}
	}
	cout<<dp[k][m];
	return 0;
}
南沙C++信奧賽陳老師解一本通題 1270:【例9.14】混合揹包

相關文章