拿了第i号物品后依然可以再拿第i号物品,考虑第i个物品的状态转移方程改一点
#include <iostream>
using namespace std;
const int MAXN=100+10;
const int MAXM=1e5+10;
int dp[MAXN][MAXM];
int weight[MAXN];
int value[MAXN];
int main() {
int n,m;
while (scanf("%d",&n)!=EOF){
for(int i=1;i<=n;++i){ //1-n号物品
scanf("%d%d",&value[i],&weight[i]);
}
scanf("%d",&m);
for(int i=0;i<=n;++i)
dp[i][0]=0;
for(int j=0;j<=m;++j)
dp[0][j]=0;
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
if(j<weight[i]) dp[i][j]=dp[i-1][j];
else dp[i][j]=max(dp[i-1][j],dp[i][j-weight[i]]+value[i]);
}
}
printf("%d\n",dp[n][m]);
}
return 0;
}
测试样例:
input:
3
3 3
7 7
9 9
10
output:
10
因为考虑i号物品时的转移方程中为dp[i,j-weght[i]],依赖于B更新后的值,和dp[i-1][j],所以从左向右更新
#include <iostream>
using namespace std;
const int MAXN=100+10;
const int MAXM=1e5+10;
int dp[MAXM];
int weight[MAXN];
int value[MAXN];
int main() {
int n,m;
while (scanf("%d",&n)!=EOF){
for(int i=1;i<=n;++i){ //1-n号物品
scanf("%d%d",&value[i],&weight[i]);
}
scanf("%d",&m);
for(int j=0;j<=m;++j)
dp[j]=0;
for(int i=1;i<=n;++i){
for(int j=weight[i];j<=m;++j){ //从左到右更新,j<weight[i]时,不放入i号物品,dp[j]=dp[j]自动成立
dp[j]=max(dp[j],dp[j-weight[i]]+value[i]); //不放入i号物品情况下的最大价值和放入情况下的最大价值中的较大值为容重j情况下的最大价值
}
}
printf("%d\n",dp[m]);
}
system("pause");
return 0;
}