有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 jthen 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.