解题报告 逃跑未遂

                         

   二.zj之逃跑未遂

众所周知,zj同学曾经被尼玛大哥抓过。话说那是一个下午大课间,zj同学没有做眼保健操就去超市买东西了,可是不小心碰上了尼玛大哥,zj0.01秒的反应时间后,撒腿就往后跑,他的后面是一条柏油马路,马路不是平坦的,是建在钢板上的,钢板又是建在一些地基上的,每一个地基都有一个高度,一块钢板是平行的,是从一个地基铺到另一个地基的(所以中间的地基不能高于此位置的钢板)(可以是上坡,也可以是下坡),但这两个地基之间最多有k-1个地基。问zj从逃跑点(起点)到教学楼(终点)的路中最少用到几个地基。

输入格式

第一行是N和K,2<=N<=5000,1<=K<=N-1。接下来N行,按顺序是地基的高度h,0<=h<=1000 0000 00。

输出格式

一个整数,表示最少地基数,第一个(起点)和最后一个(终点)一定是被用的地基。

样例输入

13 4

0

1

0

2

4

6

8

6

8

8

9

11

12

样例输出

5

后记:

   其实zj跑的挺快的,但是你知道最后为什么还是被抓了吗?

   尼玛大哥是骑着自行车的!

 

 

这个题看似模拟,实则 DP 。

首先应用一下贪心的思想,当斜率尽可能小的时候,能扩展的节点最多。(显然)

所以转移的时候要用斜率比较小的来转移。

然后,就是上代码了(Leve)。

var

 n,m,i,j,k:longint;

 min:double;

 f:array[0..5000] of longint;

 a:array[1..5000] of longint;

begin

 assign(input,'escape.in');reset(input);

 assign(output,'escape.out');rewrite(output);

 readln(n,k);

 for i:=1 to n do

  read(a[i]);

 for i:=1 to n do

  f[i]:=i;

//初始化

 

 for i:=2 to n do

 begin

  min:=maxlongint;

  for j:=i-1 downto i-k do

  if j>0 then

    if  (a[i]-a[j])/(i-j)<=min then

 begin

  min:=(a[i]-a[j])/(i-j);   //如果这个点的斜率是当前最小的

  if f[i]>f[j]+1 then f[i]:=f[j]+1;   //就试图转移

 end;

 end;

 writeln(f[n]);

 close(input);

 close(output);

end.

posted @ 2011-10-19 19:50  木小漾  阅读(193)  评论(0编辑  收藏  举报