题意:
新学期的到来,多多明天必须去上学,今天她决定晚上玩得开心点,她喜欢看卡通。所以她希望她的叔叔买一些电影给她今晚看。她的祖父给了她 L 分钟看卡通。之后,她不得不去睡觉。多多将N个电影编号为从1到N .都是她最喜欢的电影,她希望她的叔叔买给她。每个电影有个值val,每部电影都有一个时间T。多多不会中止一个电影的播放,但有一个奇怪的问题,商店出售M个电影(而不是更少或更多),她的叔叔。如何选择M块电影从N个电影中选出最高价值和时间成本不超过L。
你有多聪明!请帮助执委郑景贤+美女多多的叔叔。
输入数据:
1 //表示样例总数
3 2 10 //每个样例的第一行表示N,M,L
11 100 //N行的每个电影的时间t和价值val
1 2
9 1
解法:
二维费用的背包问题,详见背包九讲
此题要注意初始化问题
在初始状态,只有时间为0的时候可以确定状态并出初始化为0,其余状态应初始化为负无穷大
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
class DVD
{
public:
int time;
int val;
}Movie[110];
int d[1100][110];//
/*void print(int l,int m)//调试用的一个函数
{
cout<<endl;
for(int i=0;i<=l;i++)
{
for(int j=0;j<=m;j++)
{
cout<<d[i][j]<<' ';
}
cout<<endl;
}
cout<<endl;
}*/
int main()
{
int total;
scanf("%d",&total);
while(total--)
{
int n;//N: the number of DVD that DuoDuo want buy.
int m;//M: the number of DVD that the shop can sale.
int l;//L: the longest time that her grandfather allowed to watch.
scanf("%d %d %d",&n,&m,&l);
for(int i=0;i<n;i++)
{
scanf("%d %d",&Movie[i].time,&Movie[i].val);
}
//d[i][j][k]表示前i件物品j分钟k大小的最大值
memset(d,-1,sizeof(d));//未确定的状态
for(int i=0;i<=l;i++)
{
d[i][0]=0;//唯一可以确定的状态
}
//print(l,m);
for(int i=0;i<n;i++)
{
for(int j=l;j>=Movie[i].time;j--)
{
for(int k=m;k>=1;k--)
{
if(d[j-Movie[i].time][k-1]==-1)//未确定的状态显然不能转移
{
continue;
}
if(d[j][k]<d[j-Movie[i].time][k-1]+Movie[i].val)
{
d[j][k]=d[j-Movie[i].time][k-1]+Movie[i].val;
}
}
}
//print(l,m);
}
if(d[l][m]==-1)
{
printf("0\n");
continue;
}
printf("%d\n",d[l][m]);
}
return 0;
}