1085] 揹包問題(動態規劃)
阿新 • • 發佈:2019-02-08
Problem Description
在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
題解:
dp[i][j]:第i個物品前能裝入容量為j的揹包中的物品的最大價值
兩層for迴圈,i從1~N,j從1~W
當j>=v[i]即揹包容量大於物品容量時:
dp[i][j]=max(dp[i-1][j],dp[i-1][j-v[i]]+p[i]);
else
dp[i][j]=dp[i-1][j];
Code:
二維實現:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<iostream>
#include<stack>
using namespace std;
int v[110];
int p[110];
int dp[110][10010];
//int main()
//{
// int N,W;
// scanf("%d%d",&N,&W);
// for(int i=1;i<=N;i++)
// scanf("%d%d",&v[i],&p[i]);
// memset(dp,0,sizeof(dp));
// for(int i=1;i<=N;i++)
// {
// for(int j=0;j<v[i]&&j<W;j++)
// dp[i][j]=dp[i-1][j];
// for(int j=v[i];j<=W;j++)
// dp[i][j]=max(dp[i-1][j],dp[i-1][j-v[i]]+p[i]);
// }
// printf("%d\n",dp[N][W]);
//return 0;
//}
int main()
{
int N,W;
scanf("%d%d",&N,&W);
for(int i=1;i<=N;i++)
scanf("%d%d",&v[i],&p[i]);
memset(dp,0,sizeof(dp));
for(int i=1;i<=N;i++)
for(int j=1;j<=W;j++)
{
if(j>=v[i])
dp[i][j]=max(dp[i-1][j],dp[i-1][j-v[i]]+p[i]);
else
dp[i][j]=dp[i-1][j];
}
printf("%d\n",dp[N][W]);
return 0;
}
一維實現
dp[i]表示在重量為i時能容納的最多價值
Code:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<iostream>
#include<stack>
using namespace std;
int v,p;
int dp[10010];
int main()
{
int N,W;
scanf("%d%d",&N,&W);
memset(dp,0,sizeof(dp));
for(int i=1;i<=N;i++)
{
scanf("%d%d",&v,&p);
for(int j=W;j>=v;j--)
dp[j]=max(dp[j],dp[j-v]+p);
}
printf("%d\n",dp[W]);
return 0;
}