题目连接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;
}