这个题目如果你知道它的转移方程,那很简单,但如果不知道,也可以通过画图来一步步推出。
(上面自己画的,可能有点丑)
解题过程:
1、看到上面的图你想到了啥?对,没错,就是二维数组。所以我们先定义一个数组,记得赋值为0;这里我定义了一个dp[ ][ ](因为这里用的是动态规划嘛)
2、要如何保证dp[ ][ ]里面装的就是最大值呢?如果我们是找两个数中的最大值,那我们会怎么样,肯定是比较,这里也是同样的道理,因为这里是一步一步得到结果的,所以我们只用比较每一步和他的前一步就可以了
3、由图可以推出转移方程为
dp[i][j]=dp[i-1][j](第i种物品不放进背包)
dp[i][j]=dp[i-1][j-obj[i].vi]+obj[i].pi(第i种物品放进背包)
下面是完成以后的图
//血的教训一定要记得数组开大,数组开大,至少比题目中它给出的数字要大
#include <stdio.h>
struct node
{
int vi;
int pi;
};
int dp[1010][1010]={0};
int main()
{
int N,V;
struct node obj[10000];
//输入背包重量和物品数量
scanf("%d %d",&N,&V);
//注意输入要从一开始因为0
for(int i=1; i<=N; i++)
{
scanf("%d %d",&obj[i].vi,&obj[i].pi);
}
for(int i=1; i<=N; i++)
{
for(int j=1; j<=V; j++)
{
if(j<obj[i].vi)
dp[i][j]=dp[i-1][j];
else
{
if(dp[i-1][j]>dp[i-1][j-obj[i].vi]+obj[i].pi)
dp[i][j]=dp[i-1][j];
else
dp[i][j]=dp[i-1][j-obj[i].vi]+obj[i].pi;
}
}
}
// 其实这里可以直接把推理的图输出;
// for(int i=0; i<=N; i++)
// {
// for(int j=0; j<=V; j++)
// printf("%d ",dp[i][j]);
// printf("\n");
// }
printf("%d\n",dp[N][V]);
return 0;
}