特种部队

【题目描述】

特种部队到达仓库时候,发现这个仓库的锁是一把很诡异的电子锁,上面是一排按钮,每个按钮上都有一个数字。

要解开这把锁,首先要从左边的第一个按钮开始向右按动,中间可以跳过某些按钮,按动到最右边的按钮后,反向向左按动。最终,每个按钮都要按且仅按一次。每两个相邻按钮上数字之差的总和的最小值,便是解开这把锁的密码。

作为一支装备精良的特种部队,必须要在最短的时间内解开这把锁。

【输入描述】

第一行是一个n(2 <= n <= 1000)表示共有n个按钮;
第二行是n个正整数,代表从左至右各按钮上的数字,数值均不超过2000。

【输出描述】

只有一个数,为这把锁的密码。

【样例输入】

5

1 2 3 4 5

【样例输出】

4

源代码:

#include<cstdio>
#include
<cstring> #include<algorithm> using namespace std; int n,i[1001],f[1001][1001]; int Solve(int t1,int t2) //坑爹的倒推。 { if (f[t1][t2]!=-1) //已得出解,类似于记忆化搜索。 return f[t1][t2]; if (t1==1) //边界,为f[1][1],自然相差为0。 return 0; f[t1][t2]=min(Solve(t1-1,t2)+abs(i[t1-1]-i[t1]),Solve(t1-1,t1)+abs(i[t1-1]-i[t2])); //|?|t1|...|t2| ----> 显然?由f[t1-1][t2]和f[t1-1][t1]推得的。 return f[t1][t2]; } int main() { memset(f,-1,sizeof(f)); scanf("%d",&n); for (int a=1;a<=n;a++) scanf("%d",&i[a]); printf("%d",Solve(n,n)); return 0; } /* 如此神奇的DP: 可以看做2个指针同时从左端出发,不重复地遍历所有点。 f[i][j]表示1~max(i,j)的点已全部被走过,且规定i<j。 则下一步就可影响f[i][j+1]或f[j][j+1]。(j+2)理论上固然可以,但无法确定(j+1)是否已被遍历,且(j+2)可看做遍历完(j+1)后所继续推得的状态。 */
原文地址:https://www.cnblogs.com/Ackermann/p/5572080.html