1. 程式人生 > >BZOJ1775[USACO 2009 Dec Gold 3.Video Game Troubles]——DP

BZOJ1775[USACO 2009 Dec Gold 3.Video Game Troubles]——DP

表示 題目 mat borde can led cstring 背包 遊戲平臺

題目描述

技術分享圖片

輸入

* 第1行: 兩個由空格隔開的整數: N和V * 第2到第N+1行: 第i+1行表示第i種遊戲平臺的價格和可以在這種遊戲平臺上面運行的遊 戲。包含: P_i, G_i還有G_i對由空格隔開的整數GP_j, PV_j

輸出

* 第1行: 農夫約翰在預算內可以得到的最大的產出值。

樣例輸入

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

樣例輸出

210
一看到這題第一感覺就是背包,這題確實就是背包,只不過和平常的背包有些不同,在賣一些東西之前要先買另一個東西,而且這個東西還沒有價值(雖然有沒有價值不太重要qwq)。既然買遊戲的前提是買遊戲平臺,那麽我們不妨以是否買遊戲平臺做狀態來轉移,設f[i][j]代表不買第i個遊戲平臺總共花了j元的最大價值、g[i][j]代表買第i個遊戲平臺總共花了j元的最大價值。對於買了遊戲平臺的狀態(也就是每個g[i][j])再對它包含的遊戲進行狀態轉移。但要註意數組初始值要賦成極小值來避免無用狀態的轉移。
最後附上代碼。 技術分享圖片
 1 #include<queue>
 2 #include<cmath>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<iostream>
 6 #include<algorithm>
 7 using namespace std;
 8 int n,m;
 9 int x,y;
10 int v,c;
11 int g[51][100010];
12 int f[51][100010];
13 int main()
14
{ 15 scanf("%d%d",&n,&m); 16 memset(g,0x80,sizeof(g)); 17 memset(f,0x80,sizeof(f)); 18 for(int i=0;i<=m;i++) 19 { 20 g[0][i]=f[0][i]=0; 21 } 22 for(int i=1;i<=n;i++) 23 { 24 scanf("%d%d",&v,&c); 25 26 for(int
j=0;j<=m;j++) 27 { 28 f[i][j]=max(f[i-1][j],g[i-1][j]); 29 if(v<=j) 30 { 31 g[i][j]=max(g[i-1][j-v],f[i-1][j-v]); 32 } 33 } 34 while(c--) 35 { 36 scanf("%d%d",&x,&y); 37 for(int j=m;j>=v;j--) 38 { 39 g[i][j]=max(g[i][j],g[i][j-x]+y); 40 } 41 } 42 } 43 printf("%d",max(f[n][m],g[n][m])); 44 }
View Code

BZOJ1775[USACO 2009 Dec Gold 3.Video Game Troubles]——DP