51nod1085 揹包問題【動態規劃】
阿新 • • 發佈:2018-12-12
在N件物品取出若干件放在容量為W的揹包裡,每件物品的體積為W1,W2……Wn(Wi為整數),與之相對應的價值為P1,P2……Pn(Pi為整數)。求揹包能夠容納的最大價值。
Input
第1行,2個整數,N和W中間用空格隔開。N為物品的數量,W為揹包的容量。(1 <= N <= 100,1 <= W <= 10000) 第2 - N + 1行,每行2個整數,Wi和Pi,分別是物品的體積和物品的價值。(1 <= Wi, Pi <= 10000)
Output
輸出可以容納的最大價值。
Input示例
3 6 2 5 3 8 4 9
Output示例
14
思路:典型的01揹包,根據遞推關係式dp[i+1][j]=max(dp[ i ][ j ],dp[ i ][ j - w[i] ]+ v[ i ]) 即可求解。
#include <iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; int dp[105][10005],c[10005],w[10005]; int main() { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) scanf("%d%d",&w[i],&c[i]); memset(dp,0,sizeof(dp)); for(int i=1;i<=n;++i) { for(int j=1;j<=m;++j) { if(j<w[i]) dp[i][j]=dp[i-1][j]; else dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+c[i]); } } printf("%d\n",dp[n][m]); return 0; }
另外我們可以將其優化成一維陣列,減少記憶體。
#include <iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; int dp[13000],c[10005],w[10005]; int main() { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) scanf("%d%d",&w[i],&c[i]); memset(dp,0,sizeof(dp)); for(int i=1;i<=n;++i) { for(int j=m;j>=w[i];--j) { dp[j]=max(dp[j],dp[j-w[i]]+c[i]); } } printf("%d\n",dp[m]); return 0; }