题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3496
题目的大致意思就是duoduo想看电影,准备了n个想买对碟片对时间和价值,他爷爷只允许他看L时间对电影,并且商店只能批量出售,也就是一次只能出售m张,问应该如何购买,才能使总价值最大,且总时间不能超过L;
这个题就是个二维的背包问题,且每个物品只能取0次或1次;
定义f[k][j]为取k个物品且最长长度不超过j的最大价值,则f[k][j]=max(f[k][j],f[k-1][j-a[i].l]+a[i].w);
这里要注意对是对数组初始化对时候都赋成-无穷;但是f[0][0]为0;
这个赋成负无穷为给搞了半天,想用memset,但是之前没用过他,搞了半天才知道0x80是负无穷;
参考代码:
#include <iostream>
#include <cstring>
using namespace std;
struct tt
{
int l;
int w;
}a[1001];
int m,l,n;
int f[101][1001];
void execute()
{
memset(f,0x80,sizeof(f));
f[0][0]=0;
for(int i=0;i<n;i++)
{
for(int k=m;k>=1;--k)
{
for(int j=l;j>=a[i].l;--j)
{
if(f[k][j]<f[k-1][j-a[i].l]+a[i].w)
f[k][j]=f[k-1][j-a[i].l]+a[i].w;
}
}
}
int ans=0;
for(int i=0;i<=l;i++)
if(f[m][i]>ans)
ans=f[m][i];
cout<<ans<<endl;
}
int main()
{
int T;
cin>>T;
while(T--)
{
cin>>n>>m>>l;
for(int i=0;i<n;i++)
{
cin>>a[i].l>>a[i].w;
if(a[i].l>l)
{
i--;
n--;
}
}
if(n<m)
cout<<0<<endl;
else
execute();
}
return 0;
}