公交汽车--背包再次应用

[题目描述]

一个特别的单行街道在每公里处有一个汽车站。顾客根据他们乘坐汽车的公里数来付费。例如下表就是一个费用的单子。
kilometres  1  2  3  4  5  6  7 8  9  10
price   12 21 31 40 49 58 69 79 90 101
没有一辆车子行驶超过10公里,一个顾客打算行驶n公里(1<=n<=100),它可以通过无限次的换车来完成旅程。最后要求费用最少。
[输入]
第一行十个整数分别表示行走1到10公里的费用(<=500)。注意这些数并无实际的经济意义,即行驶10公里费用可能比行驶一公里少。
第二行一个整数n表示,旅客的总路程数。
[输出]
仅一个整数表示最少费用。

[输入]
12 21 31 40 49 58 69 79 90 101
15
[输出]
147

题解:

看背包看多了,看完第一想法就是多重背包..

f[i]表示花费i费用所行走的最长路程.

多重背包思想(具体参见dd_engi 牛的《背包九讲》,云盘下载(PDF):http://yunpan.cn/lk/sVkjqiHcjCJXn)

v[i]行走w[i]公里花费的价钱

w[i]其实就是i..(...).

i:=0..V 若f[i]>=n了,i 即为最低价钱.

//写到这总觉得有点儿什么问题,求解..

//好吧,想到了第二种方法,

Code1:

 1 Function Max(a,b:longint):longint; Begin if a>b Then Exit(a) Else Exit(b); End;
 2 Var
 3   f:Array[0..50000] of longint;
 4   Num,v,w:Array[0..11] of longint;
 5   i,n:longint;
 6   Vv:longint;
 7 Procedure ZeroOnePack(Cost,Weight:longint);
 8   Var
 9     j:longint;
10   Begin
11     For j:=Vv Downto Cost Do
12       f[j]:=Max(f[j],f[j-Cost]+Weight);
13   End;
14 Procedure CompletePack(Cost,Weight:longint);
15   Var
16     j:longint;
17   Begin
18     For j:=Cost to Vv do
19       f[j]:=Max(f[j],f[j-Cost]+Weight);
20   End;
21 Procedure MultiplePack(Cost,Weight,Amount:longint);
22   Var
23     k:longint;
24   Begin
25     if Cost*Amount>=Vv Then
26       Begin
27         CompletePack(Cost,Weight);
28         Exit;
29       End;
30     k:=1;
31     While k<Amount do
32       Begin
33         ZeroOnePack(Cost*k,Weight*k);
34         Dec(Amount,k);
35         k:=k Shl 1;
36       End;
37     ZeroOnePack(Amount*Cost,Amount*Weight);
38   End;
39 Begin
40   For i:=1 to 10 do
41     Begin
42       Read(v[i]);
43     End;
44   For i:=1 to 10 do W[i]:=i;
45   Read(n);
46   For i:=1 to 10 do
47     Vv:=Max(v[i]*(n Div i +1),Vv);
48   For i:=1 to 10 do Num[i]:=n Div i;
49   For i:=1 to 10 do
50     MultiplePack(v[i],w[i],Num[i]);
51   For i:=0 to Vv do
52     if f[i]>=n Then Begin Writeln(i); Halt; End;
53   //555..一开始光看样例了写成了f[i]>=15..居然还对一个点..
54 End.
55 (*)2012/11/07(*)

Code2:

完全背包..
看上去靠谱了许多..

f[i]为走了这么多路所需的最小价值...

似乎好简单..//55...为什么一开始非要写复杂的多重背包.

 1 Function Min(a,b:longint):longint; Begin if a<b Then Exit(a) Else Exit(b); End;
 2 Var
 3   f:Array[0..50000] of longint;
 4   v:Array[0..11] of longint;
 5   i,n:longint;
 6 Procedure CompletePack(Weight:longint);
 7   Var
 8     j:longint;
 9   Begin
10     For j:=i to n do
11       if f[j]=0 Then f[j]:=f[j-i]+Weight
12       Else f[j]:=Min(f[j],f[j-i]+Weight);
13   End;
14 Begin
15   For i:=1 to 10 do Read(v[i]);
16   Read(n);
17   For i:=1 to 10 do
18     CompletePack(v[i]);
19   Writeln(f[n]);
20 End.

 

 

posted @ 2012-11-07 10:42  Iris.Catch-22.S、`  阅读(194)  评论(0编辑  收藏  举报