Description
给定n位密码锁。每次可以使相邻的1-3位密码锁同时向上或向下转,即,使数字加一或者减一。给定初始状态和目标状态,问至少要转多少次。
Input
初始密码
目标密码
Output
最少的次数
Sample Input
896521
183995
Sample Output
12
这是一道简单的DP题。但是最开始我写出的状态转移方程显然没有考虑到后效性。
最开始的想法很简单,就是dp[i]表示前i位与密码相同时最少转的次数。考虑转第i位。很明显转i位的同时可以转i+1 ,i+2 位此时若只考虑前i位显然忽略的后效性。
解决后效性的方法:改变状态转移方程。改变dp表示的状态,多加入一些条件。
前面也说了考虑i+1 i+2位, 不妨记录状态dp[i][m][n] 表示转好前i位且此时第i+1位是m,i+2位是n的最小次数。考虑最终的答案,不妨让数组多开2个数。答案就是max(dp[n][x][y])x,y位任意两个数 就好了。
状态转移方程。
for(int i=0;i<=up;i++)//用2转移的范围
for(int j=0;j<=i;j++) ans=min(ans,DP(d+1,(y+i)%10,(z+j)%10,a[d+3])+up);//用3转移的范围
for(int i=0;i<=down;i++)
for(int j=0;j<=i;j++) ans=min(ans,DP(d+1,(y+10-i)%10,(z+10-j)%10,a[d+3])+down);