题目描述
Eric喜欢使用数字1,2,3,4作为密码,而且他有个怪癖,相邻数字不能相同,且相差不能超过2。当然只用数字做密码,会比较弱,Eric想知道当长度为n时,这样的密码有多少种?
输入
第一行是一个整数T(1≤T≤45),表示样例的个数。 每行一个样例,为整数n(1≤T≤45)。
输出
每行输出一个样例的结果。
样例输入
5 1 2 3 4 5样例输出
4 10 26 66 170
解题思路:这题就用递推的方法来解。 何为递推?顾名思义,就是一步一步的推理~~,答案是推出来的。 然后从 相邻数字不能相同,且相差不能超过2 这个条件入手。
当长度n==1时,密码有几种情况? 秒答:1、2、3、4 四种情况,
那长度n==2时,有几种情况?这时就已经要开始递推了。当第一位数字是1,第二位数字可为 2、3,当第一位数字是2,第二位数字可为 1、3、4,当第一位数字是3,第二位数字可为 1、2、4,当第一位数字是4,第二位数字可为 2、3。 这是一共就是 2+3+3+2种情况。
此时如果你能具有一定的敏感性,懂得逆向思考一下,这题已经解决了。如果我先规定第2位的数字,然后再考虑前面的情况。规定是1,那第一位只能是2、3,规定是2,那第一位只能是1、3、4........
推广:先规定第n位的数字,然后找到符合条件的第n-1位数和它匹配。 那就是 第n位是1的种类数等于,第n-1位是2的种类数+第n-1位是3的种类数;第n位是2的种类数等于,第n-1位是1的种类数+第n-1位是3的种类数+第n-1位是4的种类数........
现在你是否能得出答案。(注意这种情况数字都很大,往往要考虑是否会爆int)
AC代码:
- #include
-
- int T,N;
- __int64 ak47[50][5];
- __int64 ans;
-
- void slove()
- {
- ak47[1][1] = ak47[1][2] = ak47[1][3] = ak47[1][4] = 1;
- for (int i = 2; i <= 45; i ++)
- {
- ak47[i][1] = ak47[i-1][2]+ak47[i-1][3];
- ak47[i][2] = ak47[i-1][1]+ak47[i-1][3]+ak47[i-1][4];
- ak47[i][3] = ak47[i-1][1]+ak47[i-1][2]+ak47[i-1][4];
- ak47[i][4] = ak47[i-1][2]+ak47[i-1][3];
- }
- }
-
- int main()
- {
- slove(); // 递推
- scanf("%d",&T);
- while ( T --)
- {
- scanf("%d",&N);
- ans = ak47[N][1]+ak47[N][2]+ak47[N][3]+ak47[N][4];
- printf("%I64d\n",ans);
- }
- return 0;
- }