jzoj P1593 电视游戏问题

题目大意

有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

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.

你可能感兴趣的:(pascal,动态规划)