汉诺塔(记录每种路径次数)
https://ac.nowcoder.com/acm/contest/3004/I
题意:输出汉诺塔移动过程中每一种移动的次数和移动总数。
如下
A->B:XX
A->C:XX
B->A:XX
B->C:XX
C->A:XX
C->B:XX
SUM:XX
解法:记忆化搜索,当前状态的可以由上一状态得到。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <string>
#include <stdio.h>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <string.h>
#include <vector>
#define ME(x , y) memset(x , y , sizeof(x))
#define SF(n) scanf("%d" , &n)
#define rep(i , n) for(int i = 0 ; i < n ; i ++)
#define INF 0x3f3f3f3f
#define mod 998244353
#define PI acos(-1)
using namespace std;
typedef long long ll ;
const int maxn = 110;
int n , m , k , t;
struct node{
ll ab , ac , ba , bc , ca , cb;
}dp[maxn];
bool vis[maxn];
node hanio(int n , int a, int b , int c){
if(vis[n]) return dp[n];
node x = hanio(n-1 , a , c , b);
dp[n].ab += x.ac;
dp[n].ac += x.ab;
dp[n].ba += x.ca;
dp[n].ca += x.ba;
dp[n].bc += x.cb;
dp[n].cb += x.bc;
dp[n].ac++;
x = hanio(n-1 , b , a , c);
dp[n].ab += x.ba;
dp[n].ac += x.bc;
dp[n].ba += x.ab;
dp[n].ca += x.cb;
dp[n].bc += x.ac;
dp[n].cb += x.ca;
vis[n] = 1;
return dp[n];
}
int main()
{
vis[1] = 1 ;
dp[1].ab = dp[1].ba = dp[1].bc = dp[1].ca = dp[1].cb = 0;
dp[1].ac = 1 ;
int n ; cin >> n;
hanio(n , 1 , 2 , 3);
ll sum = (1ll<<n)-1ll;
cout << "A->B:" << dp[n].ab << endl;
cout << "A->C:" << dp[n].ac << endl;
cout << "B->A:" << dp[n].ba << endl;
cout << "B->C:" << dp[n].bc << endl;
cout << "C->A:" << dp[n].ca << endl;
cout << "C->B:" << dp[n].cb << endl;
cout << "SUM:" << sum << endl;
return 0 ;
}
也可打表找规律。

浙公网安备 33010602011771号