動態規劃:NYOJ 311 完全揹包

完全揹包,題意很直接。emmm...就喜歡這麼直接的題

完全揹包

時間限制:3500 ms  |  內存限制:65535 KB
難度:4
描述

直接說題意,完全揹包定義有N種物品和一個容量爲V的揹包,每種物品都有無限件可用。第i種物品的體積是c,價值是w。求解將哪些物品裝入揹包可使這些物品的體積總和不超過揹包容量,且價值總和最大。本題要求是揹包恰好裝滿揹包時,求出最大價值總和是多少。如果不能恰好裝滿揹包,輸出NO

輸入
第一行: N 表示有多少組測試數據(N<7)。
接下來每組測試數據的第一行有兩個整數M,V。 M表示物品種類的數目,V表示揹包的總容量。(0<M<=2000,0<V<=50000)
接下來的M行每行有兩個整數c,w分別表示每種物品的重量和價值(0<c<100000,0<w<100000)
輸出
對應每組測試數據輸出結果(如果能恰好裝滿揹包,輸出裝滿揹包時揹包內物品的最大價值總和。 如果不能恰好裝滿揹包,輸出NO)
樣例輸入
2
1 5
2 2
2 5
2 2
5 1
樣例輸出
NO
1
純屬自己做的記錄,自己上代碼
因爲每一個物品都不限量,所以可以重複用很多次,那麼動態規劃就是每個物品在裝不超過揹包上限的情況下,都裝進去試試,取價值最大的保留下來。我把代碼做了空間上的優化。實際上,這跟01揹包的區別就在於01揹包的狀態轉移方程是
f[i][v]=max(f[i-1][v],f[i-1][v-c[i]]+w[i]),即每裝一個物品的狀態是從上一步繼承下來的。
而完全揹包f[i][v]=max(f[i][v],f[i+1][j-c[i]]+v[i]),是跟當前的進行比較。具體的還要結合程序進行體會
 
#include<string.h>
#include<stdio.h>
int main()
{
	int dp[50010];
	int c;	//重量
	int v;	//價值 
	int N;
	scanf("%d",&N);
	while(N--)
	{
		memset(dp,-100,sizeof(dp));
		dp[0]=0;
		int M,V,i,j;
		scanf("%d%d",&M,&V);
		for(i=1;i<=M;i++)
		{
			scanf("%d%d",&c,&v);
			for(j=0;j<=V;j++)
			{
				if(j>=c)
					dp[j]=dp[j-c]+v>dp[j]?dp[j-c]+v:dp[j];
			}
		}
		if(dp[V]<0)
			printf("NO\n");
		else
			printf("%d\n",dp[V]);
	}
	return 0;
 }         


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章