算法:DP
分析:4根柱子的汉诺塔问题,很经典的问题。
对于这道题,我们依然可以将它看成是三根柱子的,用h3[i]表示用三根柱子移动i个圆盘用的最少步数,用h4[i]表示用四根柱子移动i个圆盘用的最少步数。
那么h4[i]=min(h4[i],h4[i-j]*2+h3[j]),即将总的圆盘分成两个部分,部分A利用四个圆盘移动到柱子二,部分B利用剩下的三个圆盘移动到柱子四,然后部分A再利用四个圆盘移动到柱子四,至此移动完成,刚好为上面的式子。
通过循环来枚举两个部分。
反思:DP一定要敢想,有时候想到了,一道题就做出来了。
分析:4根柱子的汉诺塔问题,很经典的问题。
对于这道题,我们依然可以将它看成是三根柱子的,用h3[i]表示用三根柱子移动i个圆盘用的最少步数,用h4[i]表示用四根柱子移动i个圆盘用的最少步数。
那么h4[i]=min(h4[i],h4[i-j]*2+h3[j]),即将总的圆盘分成两个部分,部分A利用四个圆盘移动到柱子二,部分B利用剩下的三个圆盘移动到柱子四,然后部分A再利用四个圆盘移动到柱子四,至此移动完成,刚好为上面的式子。
通过循环来枚举两个部分。
反思:DP一定要敢想,有时候想到了,一道题就做出来了。
program Vijos1073;
const
maxn=50000;
var
n:longint;
h3,h4:array [0..maxn] of longint;
procedure init;
var
i:longint;
begin
fillchar(h3,sizeof(h3),0);
fillchar(h4,sizeof(h4),0);
readln(n);
for i:=1 to n do h3[i]:=(1 shl i)-1;
end;
function min(x,y:longint):longint;
begin
if x<y then exit(x) else exit(y);
end;
procedure main;
var
i,j:longint;
begin
for i:=1 to n do
begin
h4[i]:=maxlongint;
for j:=1 to i do h4[i]:=min(h4[i],(h4[i-j] shl 1)+h3[j]);
end;
end;
begin
assign(input,'VJ1073.in'); reset(input);
assign(output,'VJ1073.out'); rewrite(output);
init;
main;
writeln(h4[n]);
close(input); close(output);
end.
本文详细解析了使用动态规划解决汉诺塔问题的方法,包括状态转移方程的建立和算法实现,深入理解动态规划在解决递归问题时的优势。
679

被折叠的 条评论
为什么被折叠?



