[Ybtoj High-efficiency Advanced 1.1] [再帰]奇妙なハノイの塔

[Ybtoj High-efficiency Advanced 1.1] [再帰]奇妙なハノイの塔

トピック

ここに画像の説明を挿入します


問題解決のアイデア

まず、タワーが3つしかないことを考慮してください
。iを移動するための最適なステップ数はm [i]です。
合計n個のリングを移動する場合

  • 最初にn-1リングをタワーBに移動し、次にm [n-1]ステップが必要です
  • 次に、Cタワーにn番目のリングを置きます。1ステップかかります
  • 最後に、これらのn-1タワーをタワーCに配置します。これには、m [n-1]ステップが必要です。

これから、3つの塔の法則が得られます:
m [i] = 2 * m [i-1] +1

次に、問題を検討し
ます。4つのタワーがiを移動するための最適なステップ数はf [i]です。
最初のn-1リングの状態を知る方法はありません。

  • まず、jをタワーBに配置することを検討できます。これには、f [j]ステップが必要です。
  • 残りのnjは3タワーの問題であり、m [nj]ステップが必要です。
  • 最後に、これらのjをCタワーに配置します。これには、f [j]ステップが必要です。

したがって、4つの塔の法則が得られます
。f[i] = min(f [i]、2 * f [j] + d [nj])(1 <= j <= i)


コード

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
long long m[20],f[20];
int main()
{
    
    
    memset(f,0x7f,sizeof(f));
	m[1]=f[1]=1;
	for (int i=2;i<=12;i++)
	     m[i]=2*m[i-1]+1;  //预处理3塔 
	for (int i=2;i<=12;i++)  //枚举环数 
        for (int j=1;j<=i;j++)  //枚举先移去B塔的环数 
            f[i]=min(f[i],2*f[j]+m[i-j]);
    for (int i=1;i<=12;i++)
        printf("%lld\n",f[i]);
    return 0;
} 

おすすめ

転載: blog.csdn.net/qq_45621109/article/details/111636168