公交汽车--背包再次应用
[题目描述]
一个特别的单行街道在每公里处有一个汽车站。顾客根据他们乘坐汽车的公里数来付费。例如下表就是一个费用的单子。
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.