[BZOJ] 1775: [Usaco2009 Dec]Vidgame 电视游戏问题

1775: [Usaco2009 Dec]Vidgame 电视游戏问题

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 291  Solved: 209
[Submit][Status][Discuss]

Description

Input

* 第1行: 两个由空格隔开的整数: N和V * 第2到第N+1行: 第i+1行表示第i种游戏平台的价格和可以在这种游戏平台上面运行的游 戏。包含: P_i, G_i还有G_i对由空格隔开的整数GP_j, PV_j

Output

* 第1行: 农夫约翰在预算内可以得到的最大的产出值。

Sample Input

3 800
300 2 30 50 25 80
600 1 50 130
400 3 40 70 30 40 35 60

Sample Output

210

HINT

Source

Gold

Analysis

这真的是一个糟糕的问题

因为没有Steam :)

显然这道题写的就让人很想写DP

记录两个状态:当前平台买不买,然后针对游戏进行背包
因此我们用F和G记录当前平台买或不买

剩下的代码讲述的比我更清晰

Code

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 using namespace std;
 5 
 6 int f[55][101010],g[55][101010];
 7 int n,m,p,cnt,w,v;
 8 
 9 int main(){
10     scanf("%d%d",&n,&m);
11     
12     memset(f,0x80,sizeof(f));
13     memset(g,0x80,sizeof(g));
14     
15     for(int i = 0;i <= m;i++) f[0][i] = g[0][i] = 0;
16     
17     for(int i = 1;i <= n;i++){
18         scanf("%d%d",&p,&cnt);
19         
20         for(int j = m;j >= 0;j--){
21             f[i][j] = max(f[i-1][j],g[i-1][j]);
22             if(j >= p) g[i][j] = max(f[i-1][j-p],g[i-1][j-p]);
23         }while(cnt--){
24             scanf("%d%d",&w,&v);
25             for(int j = m;j >= w;j--)
26                 g[i][j] = max(g[i][j],g[i][j-w]+v);
27         }
28     }
29     
30     printf("%d",max(f[n][m],g[n][m]));
31     
32     return 0;
33 } 
:)
原文地址:https://www.cnblogs.com/Chorolop/p/7618362.html