DP再不学估计下一场比赛就做不出来题了;
比赛官方标程:标程题解
.
.
I.牛牛的汉诺塔
首先汉诺塔递归到23层以后就会超时了,用递归写肯定是要记忆化搜索的,可是我不会…标程里有,费了老大劲我才找到了规律,
先把前20组数据贴出来:
然后呢可以总结出规律(qaq…)
就是对于第二列的数,在这一列中:
第一个数 == 第四个数 == (第一列的第二个数+第一列的第三个数);
第三个数 == 第六个数 == (第一列的第四个数+第一列的第五个数);
第二个数 ==第一列的第一个数 * 2+1 ;
第五个数 ==第一列的第六个数 * 2;
.
所以只需要知道第一列就可以推出来下面的所有的了;
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll dp[65][10],n,res;
string s[]={"A->B:","A->C:","B->A:","B->C:","C->A:","C->B:"};
signed main(){
cin>>n;
dp[1][2]=1;
for(int i=2;i<=n;i++)
{
dp[i][1]=dp[i][4]=dp[i-1][2]+dp[i-1][3];
dp[i][3]=dp[i][6]=dp[i-1][4]+dp[i-1][5];
dp[i][2]=dp[i-1][1]*2+1;
dp[i][5]=dp[i-1][6]*2;
}
for(int i=0;i<6;i++) cout<<s[i]<<dp[n][i+1]<<endl,res+=dp[n][i+1];
cout<<"SUM:"<<res<<endl;
return 0;
}
//前20组数组
//——————————————————————————————————————————————————————
//数目:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// |
//A->B: 0 1 1 4 4 15 15 58 58 229 229 912 912 3643 3643 14566 14566 58257 58257 233020 |
//A->C: 1 1 3 3 9 9 31 31 117 117 459 459 1825 1825 7287 7287 29133 29133 116515 116515 |
//B->A: 0 0 1 1 6 6 27 27 112 112 453 453 1818 1818 7279 7279 29124 29124 116505 116505 |
//B->C: 0 1 1 4 4 15 15 58 58 229 229 912 912 3643 3643 14566 14566 58257 58257 233020 |
//C->A: 0 0 0 2 2 12 12 54 54 224 224 906 906 3636 3636 14558 14558 58248 58248 233010 |
//C->B: 0 0 1 1 6 6 27 27 112 112 453 453 1818 1818 7279 7279 29124 29124 116505 116505 |
// |
//——————————————————————————————————————————————————————