jzoj P1593 电视游戏问题

来源:互联网 发布:java 局部变量 编辑:程序博客网 时间:2024/05/22 09:46

题目大意

有N种游戏平台,每一种游戏平台的价格是P_i,并且每一种游戏平台有G_i个只能在这种平台上运行的游戏。
必须先买进一种游戏平台,才能买进在这种游戏平台上运行的游戏。
每一个游戏有一个游戏的价格GP_j,并且有一个产出值PV_j,表示一只牛在玩这个游戏之后会产出多少牛奶。
最多可以花费的金钱为V,求获得的产出值的和最大是多少。

1 <= N <= 50
1 <= P_i <= 1000
1 <= G_i <= 10
1 <= GP_j 价格 <= 100
1 <= PV_j<= 1000000
1 <= V <= 100000

题解:

这题应该很容易就想到用DP去做:
怎么实现呢?
①我们设f[i,j]表示前i个游戏平台用了j元能获得的最大产出值!
不过这样很明显无法做到最优,因为存在可选可不选的情况,所以我们考虑这2中情况可以设状态转移方程:
f[i,j,1]表示前i个游戏平台用了j元,且不选第i个游戏平台的最大产出值。
f[i,j,2]则表示选了第i个游戏平台的最大产出值.

然后
f[i,j,1]=max(f[i-1,j,1],f[i-1,j,2])
f[i,j,2]的初值则为max(f[i-1,j-p[i],1],f[i-1,j-p[i],2])
后面对f[i,j,2]的转移
就可以得出
f[i,j,2]=max(f[i,j,2],f[i,j-gp_k,2]+pv_k)

var    f:array [0..51,0..100001,1..2] of longint;    p,c,x,y,i,j,n,m,k:longint;function max(aa,bb:longint):longint;begin    if aa>bb then exit(aa);    exit(bb);end;begin   assign(input,'vidgame.in'); reset(input);   assign(output,'vidgame.out'); rewrite(output);    readln(n,m);    for i:=0 to m do      for j:=1 to 2 do f[1,i,j]:=-maxlongint;    for i:=1 to n do      begin           read(p,c);           for j:=0 to m do           begin              f[i,j,1]:=max(f[i-1,j,1],f[i-1,j,2]);              if j<p then f[i,j,2]:=-maxlongint                     else f[i,j,2]:=max(f[i-1,j-p,1],f[i-1,j-p,2]);            end;           for k:=1 to c do            begin                 read(x,y);                 for j:=m downto x do                   f[i,j,2]:=max(f[i,j-x,2]+y,f[i,j,2]);            end;           readln;      end;    writeln(max(f[n,m,1],f[n,m,2]));    close(input); close(output);end.
原创粉丝点击