NYOJ 311 完全揹包

完全揹包

時間限制:3000 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揹包:有N個重量和價值分別爲wi,vi的物品,從這些物品中挑選出總重量不超過W 的物品,求所有挑選方案中價值總和的最大值
完全揹包:有N個重量和價值分別爲wi,vi的物品,從這些物品中挑選出總重量不超過W的物品,求所有的挑選方案中價值總和的最大值,每件物品可選多個
將完全揹包轉換爲01揹包
dp[i][j]=max(dp[i-1][j-k*w[i]]+k*v[i]) (0<=k*w[i]<=W)
轉化爲一維數組 dp[i]=max(dp[j-k*w[i]]+k*v[i]) 
*/
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define MAX 50005
#define Min -0x0ffffff
using namespace std;
int c[MAX],w[MAX];
int dp[MAX];
int main(){
	int t;
	cin>>t;
	while(t--){
		int M,V;
		cin>>M>>V;
		memset(c,0,sizeof(c));
		memset(w,0,sizeof(w));
		for(int i=0;i<MAX;i++) dp[i]=Min;
		dp[0]=0;
		for(int i=0;i<M;i++){
			int C,W;
			cin>>C>>W;
			c[i]=C,w[i]=W;
		}
		for(int i=0;i<M;i++){
			for(int j=c[i];j<=V;j++){//注意此處的循環順序正好與01揹包的循環順序相反 ;可以這樣認爲,完全揹包每件可以選多件
			//當第二次即更多的選第i件物品時,它的dp[]都是有dp[j-c[i]]決定,所以需要由前往後循環 
				dp[j]= max(dp[j],dp[j-c[i]]+w[i]);
			}
		}
		if(dp[V]>0)
			cout<<dp[V]<<endl;
		else cout<<"NO"<<endl;
	}
} 


發佈了95 篇原創文章 · 獲贊 9 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章