动态规划

  • 确定状态,记所有盘子移动从AA移动到BB状态为0,从AA移动到CC状态为1;

  • nn步的状态为dp[n][0]dp[n][0]dp[n][1]dp[n][1]dp[n][0]dp[n][0] 表示为所有盘子移动到BB所需要的次数,dp[n][1]dp[n][1] 表示为所有盘子移动到CC所需要的次数。

  • nn个盘子可以移动到BB时只需要移动1次,前n1n-1个盘子一定全部都在CC上, 并且接下来要将CC上的所有盘子移动到BB上,此时所需要移动次数等同于将前n1n-1个盘子从AA移动到CC上,因此此时的状态转移为:
    dp[n][0]=1+dp[n1][1]2dp[n][0] = 1 + dp[n-1][1] * 2

  • 由此类推,所有盘子移动到CC时,一定是第nn个盘子先移动到BB之后,再移动到CC,即需要22步,而第nn个盘子移动到BB时,前n1n-1个盘子一定全部都在CC上,移动次数为dp[n1][1]dp[n-1][1],且第nn个盘子要移动到CC时,前n1n-1个盘子一定要移动到AA上,此时移动步数等价于将n1n-1个盘子从AA移动到BB的步数,即dp[n1][0]dp[n-1][0],当第nn个盘子移动到CC之后,又要将前n1n-1个盘子从AA移动到CC上。 因此此时的状态转移为:
    dp[n][1]=1+dp[n1][1]+1+dp[n1][0]+dp[n1][1]dp[n][1] = 1 + dp[n-1][1] + 1 + dp[n-1][0] + dp[n-1][1]
    即:
    dp[n][0]=1+dp[n1][1]2dp[n][0] = 1 + dp[n-1][1] * 2
    dp[n][1]=2+dp[n1][1]2+dp[n1][0]dp[n][1] = 2 + dp[n-1][1] * 2 + dp[n-1][0]

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const ll mod = 1e9+7;

ll dp[10000005][2];
int n;
int main(){
    cin>>n;
    
    dp[1][0] = 1;dp[2][0] = 5;
    dp[1][1] = 2;dp[2][1] = 7;
    
    for(int i = 3; i <= n; ++i){
        dp[i][0] = (1 + dp[i-1][1] * 2) % mod;
        dp[i][1] = (2 + dp[i-1][1] * 2 + dp[i-1][0]) % mod;
    }
    cout<<dp[n][0]<<' '<<dp[n][1]<<endl;
    return 0;
    
}