暗黑破坏神(动态规划)

Description

无聊中的小x玩起了Diablo I... 

游戏的主人公有n个魔法 

每个魔法分为若干个等级,第i个魔法有p[i]个等级(不包括0) 

每个魔法的每个等级都有一个效果值,一个j级的i种魔法的效果值为w[i][j] 

魔法升一级需要一本相应的魔法书 

购买魔法书需要金币,第i个魔法的魔法书价格为c[i] 

而小x只有m个金币(好孩子不用修改器) 

你的任务就是帮助小x决定如何购买魔法书才能使所有魔法的效果值之和最大 

开始时所有魔法为0级 效果值为0 

Input

第一行 用空格隔开的两个整数n(0
 
以下n行 描述n个魔法 

第i+1行描述 第i个魔法 格式如下(0

<=50,
<="10)"> 
c[i] p[i] w[i][1] w[i][2] ... w[i][p[i]] 

Output

第一行输出一个整数,即最大效果

Sample Input

 

 
   

 

Sample Output

 

 
   

 

Hint

0< n< =100,0< m <=500,0 < p[i] <= 50,0 < c[i] <=10

 

 

 

解题思路:

这是一个多重背包。

不过比普通的完全背包要多一个记录路径,最后先输出最优值,再输出路径即可。

时间复杂度:O(V*∑a[i,0])

 

 

程序:

var
  n,m,s,a1,x,i,j,k,max:longint;
  a,f1:array[0..500,0..500] of longint;
  w,t,f,c,f2:array[0..10000] of longint;
begin
  readln(n,m);
  for i:=1 to n do
    begin
      read(c[i],a[i,0]);
      for j:=1 to a[i,0] do
        begin
          read(x);
          inc(a1);
          w[a1]:=c[i]*j;
          t[a1]:=x;
          a[i,j]:=a1;
        end;
      readln;
    end;
  for k:=1 to n do
    for j:=m downto 0 do
      for i:=1 to a[k,0] do
        if j>=w[a[k,i]] then
          if f[j-w[a[k,i]]]+t[a[k,i]]>f[j] then
            begin
              f[j]:=f[j-w[a[k,i]]]+t[a[k,i]];
              f1[k,j]:=i;
            end;
  writeln(f[m]);
  for i:=m downto 0 do
    if f[i]>=max then begin max:=f[i]; j:=i; end;
  for i:=n downto 1 do
    begin
      f2[i]:=f1[i,j];
      j:=j-c[i]*f2[i];
    end;
  for i:=1 to n do
    writeln(f2[i]);
end.

 

 

 

版权属于: Chris

原文地址: http://blog.sina.com.cn/s/blog_83ac6af80102vjro.html

转载时必须以链接形式注明原始出处及本声明。

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