P1006晴天小猪历险记之Hill
背景
在很久很久以前,有一个动物村庄,那里是猪的乐园(^_^),村民们勤劳、勇敢、善良、团结……
不过有一天,最小的小小猪生病了,而这种病是极其罕见的,因此大家都没有储存这种药物。所以晴天小猪自告奋勇,要去采取这种药草。于是,晴天小猪的传奇故事便由此展开……
描述
这一天,他来到了一座深山的山脚下,因为只有这座深山中的一位隐者才知道这种药草的所在。但是上山的路错综复杂,由于小小猪的病情,晴天小猪想找一条需时最少的路到达山顶,但现在它一头雾水,所以向你求助。
山用一个三角形表示,从山顶依次向下有1段、2段、3段等山路,每一段用一个数字T(1<=T<=100)表示,代表晴天小猪在这一段山路上需要爬的时间,每一次它都可以朝左、右、左上、右上四个方向走。山是环形的。(注意:在任意一层的第一段也可以走到本层的最后一段或上一层的最后一段)。
晴天小猪从山的左下角出发,目的地为山顶,即隐者的小屋。
格式
输入格式
第一行有一个数n(2<=n<=1000),表示山的高度。
从第二行至第n+1行,第i+1行有i个数,每个数表示晴天小猪在这一段山路上需要爬的时间。
输出格式
一个数,即晴天小猪所需要的最短时间。
限制
各个测试点1s
提示
在山的两侧的走法略有特殊,请自己模拟一下,开始我自己都弄错了……
忘了考虑同行然后WA了。。
参考题解:
写出一个递推式
: d[i][j]=max (d[i][j-1],d[i][j+1],d[i+1][j],d[i+1][j+1]);
无疑这是一种错误的写法,因为出现了环,对于动态规划有了后效性。
后效性的出现是因为可以同行之间走,但是不会走重复的点是可以肯定的,于是想到后效性是可以消除的。
现在先考虑同行的情况。
假设某一时刻走到了 (i,j) 这一点,在下一步决策的时候,要么是(i,j-1),要么是(i,j+1),先不考虑加减之后越界的情况。而如果选择了(i,j-1)这个点,下一步再决策的时候,势必不会再重复(i,j),而只会考虑(i,j-2)。状态d[i][j]定义为从(n,1)到点(i,j)的最短距离大小,若d[i][j]来自同行某个数,只能来自d[i][j-1]或d[i][j+1]其中一个。
于是有了一个基本的思路:
对于每一行来说先向右递推,再向左递推,递推式为
:d[i][j]=min (d[i][j],d[i-1][j]+a[i][j])
向左推的递推式类似地可以写出。
每行左右递推各一次即可,环的问题根本不需要担心。d[i][j]必来自于左推和右推时更优的一条路,若将d[i][j][0]定义为表示右推的结果,d[i][j][1]表示左推的结果,则d[i][j]的最终值为min(d[i][j][0],d[i][j][1]),这样可能更好理解一点,说明左右互不影响,只是从中选择一个即可。
循环进入上一行之后,开始递推向上走的情况,和数字三角形递推式一样,不过边缘需要单独考虑,不再给出
:d[i][j]=min(d[i+1][j],d[i+1][j+1])+a[i][j]