一、原题大意:N组数据,容量为M,下面每行分别为重量weight、价值values。求在容量范围内是背包所装的价值最大
二、思路:0-1背包问题,DP类题目。
状态转移方程为:dp[j]=max(dp[j],dp[j-weight[i]]+values[j])
书上状态转移方程为:dp[i][v]=max(dp[i-1][v],dp[i-1][v-weight[i]]+values[i])。其中dp[i][v]意为前i个物品恰放入容量为v的背包所获得的最大价值,则可分解其为第i个物品放和不放两种情况,不放则为前i-1个物品放入容量为v的背包,价值为dp[i-1][v],放则为前i-1个物品放入容量为v-weight[i]的背包,价值为dp[i-1][v-weight[i]]+values[i]。
三、一些问题:当写完还是搞不明白为什么第二层for循环是递减的,就得到了问题的解。路漫漫其修远兮,我将上下而求索······
四、原题链接:http://poj.org/problem?id=3624
五、AC源代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int maxn(int i,int j)
{
return i>j?i:j;
}
int main()
{
int n,m;
int weight[3410],values[3410];
int dp[12882];
scanf("%d%d",&n,&m);
memset(dp,0,m*sizeof(int));
for(int i=1;i<=n;i++)
scanf("%d%d",&weight[i],&values[i]);
for(int i=1;i<=n;i++)
{
for(int j=m;j>=0;j--)//j为背包容量
{
//如当i=3时dp[6]=22,dp[4]=16.当i=4时dp[6]=max(dp[6],dp[4]+7)=23
if(j-weight[i]>=0)
dp[j]=maxn(dp[j],dp[j-weight[i]]+values[i]);//为了明显起见用了maxn
//printf("%d ",dp[j]);
}
//printf("\n");
}
printf("%d\n",dp[m]);
return 0;
}