【完全背包】最小乘车费用

题目:最小乘车费用 rqnoj169

题目描述

假设某条街上每一公里就有一个公共汽车站,并且乘车费用如下表:
公里数 1 2 3 4 5 6 7 8 9 10
费用 12 21 31 40 49 58 69 79 90 101
而任意一辆汽车从不行驶超过10公里。某人想行驶n公里,假设他可以任意次换车,请你帮他找到一种乘车方案,使得总费用最小
注意:10公里的费用比1公里小的情况是允许的。

输入格式

共两行,第一行为10个不超过200的整数,依次表示行驶1~10公里的费用,相邻两数间用一个空格隔开;第二行为某人想要行驶的公里数(<=100)。

输出格式

仅一行,包含一个整数,表示行使这么远所需要的最小费用。

样例输入

样例输出

 

既然可以任意换乘,那么假设一个人乘车(1,2,3)(1,2,3,4,5,6,7,8)(1,2)     这个应该看得懂吧,表示一个人第一次乘车走了3公里,然后换乘,走了8公里,又换乘,走了2公里

那么把这个整合一下即为(1,1,1,2,2,2,3,3,4,5,6,7,8)  也就是说我们可以把每公里的单价看做物品的价值,一公里看做物品的体积,然后公里数看做体积,所以就成了每个物品可以有无限个(不懂得可以再想想,如果换乘无数次,那么必然就有无数个1,甚至无数个2,3,4,5,6.....)这就是完全背包模型!

至于代码实现,这里简略说一下可以用就地滚动正序枚举的副作用来实现,具体见背包九讲http://www.cnblogs.com/oijzh/articles/dppack.html

Pascal Code

program rqnoj169;

var
  n:longint;
  a:array[0..10] of longint;
  f:array[0..100+10] of longint;

procedure init;
begin
  assign(input,'rqnoj169.in');
  assign(output,'rqnoj169.out');
  reset(input);
  rewrite(output);
end;
procedure outit;
begin
  close(input);
  close(output);
  halt;
end;

procedure readdata;
var
  i:longint;
begin
  for i:=1 to 10 do
    read(a[i]);
  read(n);
end;

procedure main;
var
  i,j:longint;
begin
  fillchar(f,sizeof(f),$7);
  f[0]:=0;
  for i:=1 to 10 do
    for j:=i to n do
    begin
      if f[j]>f[j-i]+a[i] then f[j]:=f[j-i]+a[i];
    end;
  writeln(f[n]);
end;

begin
  init;
  readdata;
  main;
  outit;
end.

 

posted @ 2012-08-19 16:28  jiangzh  阅读(476)  评论(0)    收藏  举报