1 3 2 10 11 100 1 2 9 1
3
//题意是说多多想看卡通,但是爷爷只给了L分钟,多多的购物清单有N种物品需要叔叔帮他买,每种物品多多都会给相应的价值和代价但是超市只卖M种物品,问能得到的最大价值是多少??
显然是多重背包问题,设dp[i][j]表示背包载重为j时,选取物品i个的最优解。状态转移方程:dp[i][j]=max(dp[i-1][j-w[i]]]+v[i];
关于初始化问题:
对于必须装满的背包是需要将数组初始化的,在这里要注意的是当求最大值时需要初始化成-maxlongint而求最小值时需要初始化成maxlongint,然后再将必须装满的某一维或多维体积所对应的体积为0的数组部分初始化成0。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n, m, l;
int D[101][2];
int dp[101][1001];
int main()
{
    while(scanf("%d%d%d",&n,&m,&l) != EOF)
    {
        int i, j, k;
        for(i = 1; i <= n; i++)
            scanf("%d%d",&D[i][0],&D[i][1]);
        for(i = 0; i <= m; i++)
            for(j = 0; j <= l; j++)
               dp[i][j] = -99999999; //注意初始化为负无穷大,求最大值
        for(j = 0; j <= l; j++)
            dp[0][j] = 0;//然后再将必须装满的某一维或多维体积所对应的体积为0的数组部分初始化成0
        for(i = 1; i <= n; i++)
            for(j = m; j >= 1; j--) //注意必须从m->1,否则错误!
                for(k = l; k >= D[i][0]; k--)//为了确保推出来的dp[m][l]是最大值所以m跟l必须逆序。
                    dp[j][k] = max(dp[j-1][k-D[i][0]] + D[i][1], dp[j][k]);
        
        if(dp[m][l] < 0) dp[m][l] = 0;
        printf("%d\n",dp[m][l]);
    }
    return 0;
}
#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
int main()
{
    int n,m,l,i,j,k;
    int c[101];
    int w[101];
    int dp[1001][101];
    while(~scanf("%d%d%d",&n,&m,&l))
    {
        for(i=1;i<=n;i++)
        {
            scanf("%d%d",&c[i],&w[i]);
        }
        memset(dp,-1,sizeof(dp));
        dp[0][0]=0;
        for(i=1;i<=n;i++)
        {
            for(j=l;j>=c[i];j--)
            {
                for(k=1;k<=i;k++)//k要小于i因为m<n
                {
                    if(dp[j-c[i]][k-1]!=-1)dp[j][k]=max(dp[j][k],dp[j-c[i]][k-1]+w[i]);
                }
            }
        }
        int maxx;
        maxx=0;
        for(i=0;i<=l;i++)maxx=max(maxx,dp[i][m]);
        cout<<maxx<<endl;
    }
    return 0;
}
 
Watch The Movie,布布扣,bubuko.com
原文:http://blog.csdn.net/u012773338/article/details/38295669