魔法物品(magic.pas/c/cpp)

有两种类型的物品:普通物品和魔法物品。普通物品没有魔法属性,而魔法物品拥有一些魔法属性。每种普通物品有一个价值P,但每种魔法物品有两种价值:鉴定前的价值P。和鉴定后的价值P2(当然,P2总是大于P。)。

为了鉴定一个魔法物品,你需要购买一个鉴定卷轴,用它来鉴定魔法物品。鉴定完一件魔法物品以后,鉴定卷轴便会消失。每个鉴定将会消耗Pi元钱,如果没有足够的钱,你将无法购买任何鉴定卷轴。

现在,你正在一个集市中,同时拥有很多物品。你知道每件物品的价值并且想要出售全部物品。那么,你最多能够获得多少钱呢?

    你可以假定:

    ★开始的时候你没有钱。

    ★所有的魔法物品都还没有被鉴定。

    ★只要你有足够的钱,你可以购买任意多的鉴定卷轴。

输入magic.in

    第一行有两个整数N和Pi(0<Pi≤5000),表示你拥有的物品数和一个鉴定卷轴价格。

    接下来N行,每行给出一件物品的价格。

    对于每件普通物品,那一行仅有一个整数P(0<P≤10000)。

    对于每件魔法物品,那一行将会有两个整数P1和P2(0<P1<P2≤10000)。

输出magic.out

一个整数表示你最多能够获得多少钱。

样倒输入

  2 10

  10

  20 100

样例输出

  100

数据规模

  对于30%的数据N≤50;

  对于100%的数据N≤1000。

 

  [解析]:对于题目中的普通物品和鉴定前价格加上鉴定费用大于等于鉴定后价格的物品可以直接卖掉。对于剩下的物品,只要能够买得起一个鉴定卷轴就可以把所有的物品都鉴定完。    那么问题就转化为用最小的损失凑足一个鉴定卷轴的钱,直接01背包即可。

 

 1 参考程序
 2 Var p1,p2,f  :  array  [0..5100]of longint;
 3     c:array[0..5100]of boolean;
 4     n,k,pi,i,j,sum,ss:longint;
 5 begin
 6   assign  (input,'magic.in');  reset(input);
 7   assign(output,'magic.out');rewrite(output);
 8   readln(n,pi);
 9   for i:=1 to n do begin
10     read(p1[i]);
11     inc(ss,p1[i]);
12     if not eoln then begin
13       readln(p2[i]);
14       p2[i]:=p2[i]-Pi-p1[i];
15       if p2[i]>0 then inc(sum,p2[i]+p1[i])
16        else begin 
17         p2[i]:=0;inc(sum,p1[i]);
18        end;
19      end
20     else begin
21       readln;
22       inc(sum,p1[i]);
23     end;
24   end;
25   c[0]:=true;
26   for i:=1 to pi do f[i]:=maxlongint;
27   if ss<pi  then begin
28  writeln(ss);
29 Close(output);halt;
30 end;
31   for j:=1 to n do for i:=pi-1 downto 0 do 
32 if c[i] then begin
33       k:=i+p1[j];
34       if k>pi then k:=Pi;
35       if f[i]+p2[j]<f[k] then begin
36  f[k]:=f[i]+p2[j];C[k]:=true;
37 end;
38     end;
39   writeln(sum-f[pi]);
40   close(output);
41 end.

考试时错误的算法:

 1 var
 2   n,p,i,j,kongge,money,m,n1,ans:longint;
 3   p1,p2:array[0..1000] of longint;
 4   s:array[1..1000] of string;
 5   f:array[0..1000,0..5000] of longint;
 6 function max(x,y:longint):longint;
 7 begin
 8   max:=x;
 9   if x<y then max:=y;
10 end;
11 begin
12 assign(input,'magic.in');
13 reset(input);
14 assign(output,'magic.out');
15 rewrite(output);
16   n1:=0;
17   readln(n,p);
18   for i:=1 to n do
19    begin
20      readln(s[i]);
21      kongge:=pos(' ',s[i]);
22      if kongge=0 then
23       begin
24         val(s[i],money);
25         inc(m,money);
26       end
27      else begin
28             inc(n1);
29             val(copy(s[i],1,kongge-1),p1[n1]);
30             val(copy(s[i],kongge+1,255),p2[n1]);
31           end;
32    end;
33    ans:=0;
34    for i:=1 to 1000 do f[0,i]:=m;
35    for i:=1 to n1 do
36     for j:=1 to 1000 do
37      begin
38       if f[i-1,j+1]-p>=0 then
39        f[i,j]:=max(f[i-1,j+1]-p+p2[i],f[i-1,j]+p1[i]);
40       if f[i,j]>ans then ans:=f[i,j];
41      end;
42    writeln(ans);
43 close(input);
44 close(output);
45 end.

 

posted @ 2015-11-02 19:12  ZJQCation  阅读(553)  评论(0编辑  收藏  举报