Tyvj P1106 题解与反思

  好久没做题了,今天突然想刷个水题,这个题乍看像是一个人畜无害的数字三角形。等我充分入戏后才发现,NND,竟然是一道双重DP!双重就双重吧,在我WA了N次后,发现该题有一个充分猥琐的条件——你TMD数据有环为何不写在注释里???????!!!!!!!!!

  分析题目,有这样一句话【每一次它都可以朝左、右、左上、右上四个方向走】使其由一个人畜无害的数字三角形蜕变成了一个双重DP。要先由底下一层的最优解更新上面一层,更新完后还要在该层左、右各扫一遍,才能得到该层最优解并用来更新下一层。

  于是有:

    i==(n-1) - 1

      {

       j==1 - n

        {

        f[i,j]==min(f[i+1,j+1]+a[i,j],f[i+1,j]+a[i,j])

        }

      j==2 - n

        {

        f[i,j]==min(f[i,j-1]+a[i,j],f[i,j])

        }

      j==(n-1) - 1

        {

        f[i,j]==min(f[i,j+1]+a[i,j],f[i,j])

        }

      }

  我很傻很天真的想着,然后就那么写了,结果WA得很惨。主要是因为:

    1、忽视了【晴天小猪从山的左下角出发】

    2、忽视了 【在任意一层的第一段也可以走到本层的最后一段或上一层的最后一段-> 且在任意一层的最后一段也可以走到本层的第一段或上一层的第一段】

  结果捣鼓了一个上午……

 附代码:

1 var
2 n,i,j:longint;
3 a,f:array[0..1000,0..1000]of longint;
4
5  function min(a,b:longint):longint;
6 begin
7 if a>b then exit(b) else exit(a);
8 end;
9
10
11 begin
12 {Input}
13 readln(n);
14 for i:=1 to n do
15 begin
16 for j:=1 to i do
17 read(a[i,j]);
18 readln;
19 end;
20 {Initialize}
21 fillchar(f,sizeof(f),$6f);
22 f[n,1]:=a[n,1];
23 for i:=2 to n do
24 f[n,i]:=min(f[n,i],f[n,i-1]+a[n,i]);
25 if f[n,1]+a[n,n]<f[n,n] then
26 begin
27 f[n,n]:=f[n,1]+a[n,n];
28 for i:=n-1 downto 1 do
29 f[n,i]:=min(f[n,i],f[n,i+1]+a[n,i]);
30 end;
31
32 {DP}
33 for i:=n-1 downto 1 do
34 begin
35 for j:=1 to i do
36 f[i,j]:=min(f[i+1,j]+a[i,j],f[i+1,j+1]+a[i,j]);
37 f[i,1]:=min(f[i+1,i+1]+a[i,1],f[i,1]);
38 f[i,i]:=min(f[i+1,1]+a[i,i],f[i,i]);
39
40 {------------------------------------}
41
42 f[i,i]:=min(f[i,1]+a[i,i],f[i,i]);
43 f[i,1]:=min(f[i,i]+a[i,1],f[i,1]);
44 for j:=2 to i do
45 f[i,j]:=min(f[i,j],f[i,j-1]+a[i,j]);
46
47 for j:=i-1 downto 1 do
48 f[i,j]:=min(f[i,j],f[i,j+1]+a[i,j]);
49 end;
50 {Output}
51 writeln(f[1,1]);
52 end.

posted on 2011-04-29 16:46  Lex Luthor  阅读(237)  评论(0编辑  收藏  举报

导航