完全揹包
時間限制: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; } }