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