hdu2569

/*
 * =====================================================================================
 *
 *       Filename:  hud2569.c
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  2013年11月14日 11时05分09秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Wenxian Ni (Hello World~), niwenxianq@qq.com
 *   Organization:  AMS/ICT
 *
 * =====================================================================================
 */
 /* 
彼岸


Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2460    Accepted Submission(s): 1354




Problem Description
突破蝙蝠的包围,yifenfei来到一处悬崖面前,悬崖彼岸就是前进的方向,好在现在的yifenfei已经学过御剑术,可御剑轻松飞过悬崖。
现在的问题是:悬崖中间飞着很多红,黄,蓝三种颜色的珠子,假设我们把悬崖看成一条长度为n的线段,线段上的每一单位长度空间都可能飞过红,黄,蓝三种珠子,而yifenfei必定会在该空间上碰到一种颜色的珠子。如果在连续3段单位空间碰到的珠子颜色都不一样,则yifenfei就会坠落。
比如经过长度为3的悬崖,碰到的珠子先后为 “红黄蓝”,或者 “蓝红黄” 等类似情况就会坠落,而如果是 “红黄红” 或者 “红黄黄”等情况则可以安全到达。
现在请问:yifenfei安然抵达彼岸的方法有多少种?
 
 
 


Input
输入数据首先给出一个整数C,表示测试组数。
然后是C组数据,每组包含一个正整数n (n<40)。
 


Output
对应每组输入数据,请输出一个整数,表示yifenfei安然抵达彼岸的方法数。
每组输出占一行。
 


Sample Input
2
2
3
 


Sample Output
9
21
 


Author
yifenfei
 * */
 //技巧1.把所有变量都变成维数
 //dp[n][a][b] = dp[n-1][a][a] + dp[n-1][b][a]
 //dp[n][a][a] = dp[n-1][a][a] + dp[n-1][b][a] + dp[n-1][c][a]
 //f(n) = 6*dp[n][a][b] + 3* dp[n][a][a]
#include <stdio.h>


int main()
{
    int c,n;
    int i;
    int dp[40][3][3];
    dp[2][0][0]=dp[2][0][1]=dp[2][0][2]=1;
    dp[2][1][0]=dp[2][1][1]=dp[2][1][2]=1;
    dp[2][2][0]=dp[2][2][1]=dp[2][2][2]=1;
    for(i=3;i<40;i++)
    {
        //这里有很多是相等的
        dp[i][0][1] = dp[i-1][0][0] + dp[i-1][1][0];
        dp[i][1][0] = dp[i-1][0][1] + dp[i-1][1][1];
        dp[i][0][2] = dp[i-1][2][0] + dp[i-1][0][0];
        dp[i][2][0] = dp[i-1][2][2] + dp[i-1][0][2];
        dp[i][1][2] = dp[i-1][1][1] + dp[i-1][2][1];
        dp[i][2][1] = dp[i-1][2][2] + dp[i-1][1][2];
        dp[i][0][0] = dp[i-1][0][0] + dp[i-1][1][0] + dp[i-1][2][0];
        dp[i][1][1] = dp[i-1][1][1] + dp[i-1][0][1] + dp[i-1][2][1];
        dp[i][2][2] = dp[i-1][0][2] + dp[i-1][1][2] + dp[i-1][2][2];
    }
    scanf("%d",&c);
    while(c--)
    {


       scanf("%d",&n);
        if(n==1)
           printf("3 ");
        else
           printf("%d ",6*dp[n][0][1]+3*dp[n][0][0]);
       
    }
    return 0;
}

每天早上叫醒你的不是闹钟,而是心中的梦~
原文地址:https://www.cnblogs.com/vintion/p/4117030.html