特种部队【动态规划】
双进程dp需要练习
【问题描述】
某特种部队接到一个任务,需要潜入一个仓库。该部队士兵分为两路,第一路士兵已经在正面
牵制住了敌人,第二路士兵正在悄悄地从后方秘密潜入敌人的仓库。
当他们到达仓库时候,发现这个仓库的锁是一把很诡异的电子锁,上面是一排按钮,每个按钮
上都有一个数字……10秒钟后,总部返回了该锁的技术信息。要解开这把锁,首先要从左边的第
一个按钮开始向右按动,中间可以跳过某些按钮,按动到最右边的按钮后,反向向左按动。最终,
每个按钮都要按且仅按一次。每两个相邻按钮上数字之差的总和的最小值,便是解开这把锁的密码。
作为一支装备精良的特种部队,必须要在最短的时间内完成任务,解开这把锁,潜入仓库。
【输入文件】
输入文件force.in 第一行是一个n(2 <= n <= 1000)表示共有n个按钮。
第二行是n个正整数,代表从左至右各按钮上的数字,数值均不超过2000。
【输出文件】
输出文件force.out只有一个数,为这把锁的密码。
【输入样列】
5
1 2 3 4 5
【输出样列】
4
program force;
var
cost,f:array[0..1001,0..1001] of longint;
a:array[0..1001] of longint;
n,ans:longint;
procedure init;
var i:longint;
begin
assign(input,'force.in');reset(input);
assign(output,'force.out');rewrite(output);
fillchar(a,sizeof(a),0);
ans:=100000000;
readln(n);
for i:=1 to n do read(a[i]);
end;
function min(a1,a2:longint):longint;
begin
if (a1>a2) then exit(a2) else exit(a1);
end;
procedure main;
var i,j:longint;
begin
for i:=0 to n do begin // ※ 小技巧 1只能取一次所以可以增加一个点0 但是从0跳到其他地方的权值都是0!
cost[0,i]:=0;
cost[i,0]:=0;
end;
for i:=1 to n do
for j:=1 to n do begin
if i=j then continue;
cost[i,j]:=abs(a[i]-a[j]);
end;
fillchar(f,sizeof(f),$7);
f[0,0]:=0;
for i:=0 to (n-1) do
for j:=i to n do begin
f[i,j+1]:=min(f[i,j+1],f[i,j]+cost[j+1,j]);
f[j,j+1]:=min(f[j,j+1],f[i,j]+cost[j+1,i]); //从我设置的状态来看 都是小的在前面大的在后面 所以从i跳到j+1就变成了[j,j+1]
end;
for i:=1 to n do if (ans>f[i,n]) then ans:=f[i,n]+cost[i,n];
writeln(ans);
end;
procedure terminate;
begin
close(input);close(output);
end;
begin
init;
main;
terminate;
end.
posted on 2011-10-21 22:23 ushiojamie 阅读(275) 评论(0) 编辑 收藏 举报