JZOJ 4.8 2016——最小步数【记忆化搜索】

Description

从起点到终点有N步,如果“走”第K步,将会得到A[K]元钱,A[K]可能为负数。
你也可以花100元钱“跳过”当前的这一步,即不会得到A[K]。但是任何时刻身上的钱都必须是非负的。开始时,你身上共有0元。给定数组A,求在能到达终点的情况下最小需要走过(即不是用100元钱跳过)的步数。注意:最后一步必须走,不能选择跳过。

Input

共有两行。
第一行为整数N(0<=N<=100)。
第二行有N个整数,第K个数为A[K],-10000<=A[K]<=10000,。

Output

一个整数,表示需要走的最少步数。若无法走到终点,输出-1。

Sample Input

6
30 30 30 30 30 30

Sample Output

5


记忆化搜索+剪枝
剪枝:
①如果当前已经等于最小步数,退出
②如果当前剩下的费用比原来还小,退出
然后赋值
最后跳和走两种情况搜索


代码如下:

var n,i,min:longint;
    f:array[0..101,0..101]of longint;
    a:array[0..101]of longint;

procedure search(i,j,s:longint);
begin
  if (s+1>=min)or(j<=f[i,s]) then exit;
  f[i,s]:=j;
  if (i=n) then begin if(j+a[i]>=0)and(s+1<min) then min:=s+1; exit; end;
  if (j-100>=0) then search(i+1,j-100,s);
  if (j+a[i]>=0) then search(i+1,j+a[i],s+1);
end;

begin
  readln(n);
  for i:=1 to n do read(a[i]);
  fillchar(f,sizeof(f),255);
  min:=maxlongint;
  search(1,0,0);
  if min=maxlongint then write(-1) else write(min);
end.
原文地址:https://www.cnblogs.com/Comfortable/p/8412326.html