暗黑破坏神(动态规划)

来源:互联网 发布:gta5淘宝刷金币靠谱吗 编辑:程序博客网 时间:2024/04/28 10:33

Description

无聊中的小x玩起了DiabloI... 

游戏的主人公有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

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

SampleInput

 

3 101 3 1 2 22 3 2 4 63 3 2 1 10

 

SampleOutput

 

11103

 

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:=mdownto 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
    iff[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

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

0 1