题目连接http://acm.nyist.net/JudgeOnline/problem.php?pid=289
思路:
很明显这是一道01背包的问题
设苹果的大小数组为c[i],价钱数组为w[i];
dp[i][j] 表示第1,2,.......i;个苹果放入容量为j的容器中的最大价值
首先考虑状态转移方程,遍历苹果的放入背包的时候 有两种情况,就是加上这个苹果之后 钱数是否比不加这个苹果的钱数多。 一、加上这个苹果钱数比原来大 那么dp[i][j] = dp[i - 1] [j - c[i]] + w[i];如果加上这个苹果比原来的质量小那么dp[i][j] = dp[i - 1][j];
所以状态转移方程就可以得出来 dp[i][j] = max(dp[i - 1][j],dp[i - 1][j - c] + w[i]);
这个i - 1的意思就是 如果这个苹果不放入背包中 它的最大价值应该等于1,2,....i -1个苹果放入背包中的最大价值
但是这个二位数组的占用的空间有点大 我们可以把二维数组压缩成一维的 压缩成一位的有一个重要的问题需要提醒
那就是遍历方向的问题 因为每个物品只有一个 如果j是从0开始的那么很有可能每个物品用例两次 这和题意不符 所以要把
j从最大到最小开始遍历 这样就不会让每个物品遍历两次 状态转移方程可以写出 dp[j] = max(dp[j],dp[j - c[i]] + w[i]);
#include<stdio.h> #include<string.h> int dp[1001]; int max1(int a,int b) { if(a > b) return a; return b; } int main() { int n,v,i,w,c,j; while(~scanf("%d%d",&n,&v)) //代表背包容量 { if(v == 0||n == 0)break; memset(ans,0,sizeof(ans)); for(i = 1;i <= n;i++) //从i=1时候开始 { scanf("%d%d",&c,&w); //c代表每个输入的苹果的大小 w代表价值 for(j = v;j >= c;j--) { dp[j] = max1(dp[j],dp[j - c] + w); } } printf("%d\n",dp[v]); //输出v的时候的最大价值 } return 0; }