[百度2015春季实习生招聘附加题] 今天要吃点好的!
加班了一个通宵的度度熊,神经有点恍惚,想到依然未能解决的Bug,眼泪禁不住霹雳哗啦往下掉……他抬头看了看帝都灰蒙蒙的天空,一咬牙,一跺脚,大叫一声——劳资今天要吃点好的! 已知本厂有n个食堂,第i(i属于[1,n])个食堂有m[i]种食物,每种食物有一个价钱c,享受度v,度度熊希望去一个食堂就餐,花费[bot,top]范围内的钱数(也可以拍桌子走人,哪里都不吃了),选择若干种食物,使得自己所能获得的享受度最大。(注意,度度熊还有一个挑食的特点,同一种食物他最多只会点一份。) 现在告诉你所有食堂食物的信息,希望你进行选择搭配,使得度度熊可以得到最大的享受度,并输出这个享受度的值。
输入描述:
第一行是一个正整数T(1<=T<=20),表示有T组测试数据。 对于每组数据—— 第一行是三个数n,bot,top,n代表食堂数1<=n<=10),bot是这次吃饭的最低消费,top是这次吃饭的最高消费(0<=bot,top<=10000) 接下来依次是n个食堂的信息,对于第i个食堂 第一行是一个数m[i](o<=m[i]<=100),代表第i个食堂的食物数 第二行有2*m[i]个数,分别是c[i][1],v[i][1],c[i][2],v[i][2],……c[i][m[i]],v[i][m[i]] c[i][j]表示第i个餐厅第j种食物的价钱,v[i][j]代表第i个餐厅第j种食物给度度熊带来的享受度。
输出描述:
对于每组数据,请输出一行,每行一个正整数。表示度度熊所能获得的最大享受度。 数据结果保证不会超过2^31-1.
输入例子:
2 2 10 20 5 1 1 2 1 5 1 10 1 20 1 5 1 2 2 2 5 2 10 2 20 2 2 10 10 1 5 1 1 5 1
输出例子:
8 0
题解:
首先度度熊只可能去一个餐厅用餐,所以每组数据中的每个餐厅可以独立解答。
根据数据规模o<=m[i]<=100 ;0<=bot,top<=10000,所以想到动态规划,转化为背包问题。因为花费必须在bot~top之间,即相当于物品体积至少装到bot,所以改变一下初始化,开一个二维数组f[i][j],代表装第i个物品,花费j元时的最大享受度。
对于每个餐厅初始化f[i][j]=-1;f[0][0]=0;则动态转移方程if(f[i][j]!=-1) f[i][j+c]=max(f[i-1][j+c],f[i-1][j]+v);最后扫描一下f[n][bot~top]取最大值即可。另外,可以利用滚动数组进行优化,去掉一维。
1 #include<cstdio> 2 #include<iostream> 3 #include<string.h> 4 #include<algorithm> 5 #include<math.h> 6 #include<stdbool.h> 7 #include<time.h> 8 #include<stdlib.h> 9 #include<set> 10 #include<map> 11 #include<stack> 12 #include<queue> 13 #include<vector> 14 using namespace std; 15 #define clr(x,y) memset(x,y,sizeof(x)) 16 #define sqr(x) ((x)*(x)) 17 #define all(it,s) for(it=s.begin();it!=s.end();it++) 18 #define rep(i,a,b) for(int i=(a);i<=(b);i++) 19 #define LL long long 20 #define INF 0x3f3f3f3f 21 #define A first 22 #define B second 23 #define PI acos(-1.0) 24 int f[11000]; 25 26 int main() 27 { 28 int T,n,h,t,k,c,v,maxn; 29 30 scanf("%d",&T); 31 while(T--) { 32 scanf("%d%d%d",&n,&h,&t); 33 maxn=-1; 34 while(n--) { 35 scanf("%d",&k); 36 clr(f,-1); 37 f[0]=0; 38 for(int i=0;i<k;i++) { 39 scanf("%d%d",&c,&v); 40 for(int j=t;j>=c;j--) { 41 if(f[j-c]!=-1) { 42 f[j]=max(f[j],f[j-c]+v); 43 } 44 } 45 } 46 for(int i=h;i<=t;i++) { 47 maxn=max(maxn,f[i]); 48 } 49 } 50 if(maxn==-1) puts("0"); 51 else printf("%d\n",maxn); 52 } 53 54 }