【洛谷P2967】【USACO 2009 Dec】电子游戏 Video Game Troubles
问题描述
约翰的奶牛们玩游戏成瘾!本来约翰是想把她们拖去电击治疗的,后来他发现奶牛们在生产了更多的牛奶,也就开始支持她们了。
但是,奶牛在选择游戏平台上的分歧很大:有的奶牛想买一台 Xbox 360来跑《光晕 3》;有的奶牛想要一台任天堂Wii来跑《明星大乱斗X》; 还有的奶牛想要在PlayStation 3 上玩《潜龙谍影4》。看来约翰要做一些选择才行。
已知市面上有N种平台,如果想玩第i种平台的游戏,必须先买一台该平台上的游戏机,价格为Pi。第i种平台上有Gi种游戏,其中第j个游戏的价格为GPi,j,奶牛玩过该游戏后的牛奶产出为PVi,j.如果想玩同一平台上的多个游戏,只要买一台游戏机就够了。
假设约翰的总预算不能超过V。请帮他考虑一下,购买哪些游戏机和游戏,才能使奶牛产奶的效益最大?注意一个游戏玩两次是不会有双倍效益产生的。
输入格式
第一行:两个用空格分开的整数N和V,1 ≤ N ≤ 50,1 ≤ V ≤ 106
第二行到第N + 1行:第i + 1行描述了第i个游戏平台。首先是Pi。接着是Gi,其次有Gi对整数GPi,j和PVi,j,1 ≤ Pi ≤ 1000,1 ≤ Gi ≤ 10,1 ≤ GPi,j ≤ 100,1 ≤ PVi,j ≤ 106
输出格式
第一行:单个整数,表示约翰可以得到的最高产出
样例输入
3 800
300 2 30 50 25 80
600 1 50 130
400 3 40 70 30 40 35 60
样例输出
210
提示
购买第一种游戏机上的第二个游戏和第三种游戏机上的第一、第三个游戏,预算为300 + 25 + 400 + 40 + 35 = 800,收益为80 + 70 + 60 = 210
题解
设f[j][0/1] 表示前i个游戏平台价格不超过j元的最大效益,由于要买游戏机,第i个游戏平台实际可以用的钱为j-p[i],然后就直接用01背包的模板了。
有可能不买第i个游戏平台的游戏机和所有游戏可以获得更大的效益,f[j][0]存储前i-1个游戏平台的最大收益,即不买第i个游戏平台的最大收益,f[j][1]用来推前i个游戏平台的最大收益,最后前i个游戏平台的最大收益为max(f[j][0],f[j][1])
1 #include <cstdio> 2 int n,m,p[55],g[55],w[55][15],v[55][15],f[1000005][2]; 3 int max(int x,int y) 4 { 5 return x>y?x:y; 6 } 7 int main() 8 { 9 int i,j,k; 10 scanf("%d%d",&n,&m); 11 for (i=1;i<=n;i++) 12 { 13 scanf("%d%d",&p[i],&g[i]); 14 for (j=1;j<=g[i];j++) 15 scanf("%d%d",&w[i][j],&v[i][j]); 16 } 17 for (i=1;i<=n;i++) 18 { 19 for (j=p[i];j<=m;j++) 20 f[j][1]=f[j-p[i]][0]; 21 for (j=1;j<=g[i];j++) 22 for (k=m-w[i][j];k>=p[i];k--) 23 f[k+w[i][j]][1]=max(f[k+w[i][j]][1],f[k][1]+v[i][j]); 24 for (j=p[i];j<=m;j++) 25 f[j][0]=max(f[j][0],f[j][1]); 26 } 27 printf("%d",f[m][0]); 28 return 0; 29 }