时隔多年,忽然又回来了。
记录一个小小的汉诺塔2333
没想到3年过去,我写递推还要看题解才能想明白/(ㄒoㄒ)/~~
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#if 0
Author: GoesM
Preparation for competition as MUCer
Day3--2021.8.4.
Theme: Basic DFS & BFS & dp
Title: 汉诺塔
#endif
/*题目细节:
n个盘子,4座塔,求解最短步数。
有4根柱子 第一根柱子有n个圆盘,圆盘由上至下依次变大
需要把n个圆盘移动到第四根柱子上
需要满足以下规则,圆盘只能放在比它更大的圆盘上,一次只能移动一个圆盘
*/
string note="这真是一个有趣的补漏题233";
/*
三柱子的思路:
对于n盘3柱,相当于:
先将上面的(n-1)个盘子进行“n-1盘3柱”的变换,按顺序放置在中间的柱子上。f[n-1]步
再将最底下的1个盘子挪至 最右边的柱子上。1步。
(因为最底下的盘子最大,不影响其他任何一个盘子的放置,因此:)
再将那(n-1)个盘子 进行“n-1盘3柱”的变换,按顺序放置在最右边的柱子上。f[n-1]步
因此dp解三柱问题:f[i]=f[i-1]*2+1;初始化:f[0]=0,f[1]=1;
*/
int n,f[1005],dp[1005];
/*
四柱子的思路:
对于n盘4柱,相当于:
先将上面的j个盘子进行“j盘4柱”的变换,按顺序放置在某一柱子上。dp[j]步。
(因为这个柱子放的是最上面的j个盘子,所以再移动后续盘子时,这个柱子不再能使用,因此: )
再将下面的(n-j)个盘子进行“n-j盘3柱”的变换,按顺序放置在第四根柱子上,f[n-j]步。
( 因为第四根柱子上放的时最下面的n-j个盘子,所以不影响使用,因此:)
再将之前的j个盘子进行“j盘4柱”的变换,按顺序放置在第四根柱子上。dp[j]步。
因此dp解四柱问题:dp[n]=dp[j]*2+f[n-j]
至于j应该是多少,暴搜判断。
=>时间复杂度:n2
*/
int main(){
cin>>n;for(int i=1;i<=n;i++) f[i]=f[i-1]*2+1;
memset(dp,0x3f,sizeof(dp)); dp[0]=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=i-1;j++)
dp[i]=min(dp[i],dp[j]*2+f[i-j]);
cout<<dp[n]; return 0;
}