poj2663 分治

Tri Tiling
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 9133   Accepted: 4740

Description

In how many ways can you tile a 3xn rectangle with 2x1 dominoes? 
Here is a sample tiling of a 3x12 rectangle. 

Input

Input consists of several test cases followed by a line containing -1. Each test case is a line containing an integer 0 <= n <= 30.

Output

For each test case, output one integer number giving the number of possible tilings.

Sample Input

2
8
12
-1

Sample Output

3
153
2131


题意:一个3 * n的矩阵,用1 * 2的矩阵拼凑而成,问有多少种拼法

思路:递推,先假设输入的数字模2变成一个单位 1 (因为奇数是不可以使用的,拼不满)。

有木块拼满一单位有3种可能,其他有2种可能,ans[i]表示当前的解:
       1.在此处放一单位的积木。等于 3 * ans[i-1];(就是此处一单位积木可以有三种变化形式)
       2.与前面相连接。连接的方案有 2 * (ans[i-2] + ans[i-3] +......+ ans[0]);(因为任意两个单位的在一起还有两种变化)
       因此有:ans[i] = 3 * ans[i-1] + 2 * (ans[i-2] + ans[i-3] +......+ ans[0]);--------(1)

       理解到这里应该就差不多了,当然也可以再化简为 ans[i] = 4 * ans[i-1] - ans[i-2];-----------(2)

       另外还要注意几点:1.奇数单位不能拼满。 2. 0的时候输出1(可能是出题者的假设,他忘了改了)


下面有两种方法,第一种是运用式子 1  写出的代码

第二种递归方法是用式子 2  写出来的


#include<stdio.h>

int ans[35];

int main()
{
    ans[0]=1;ans[1]=3;
    for(int i=2;i<=15;i++){
        ans[i]=3*ans[i-1];
        for(int j=0;j<i-1;j++){
            ans[i]+=2*ans[j];
        }
    }
    int n;
    while(scanf("%d",&n),n!=-1)
    {
        if(n%2!=0)
            printf("0\n");
        else
            printf("%d\n",ans[n/2]);
    }
    return 0;
}


递归调用,计算这么一个递推式子,感觉自己递归比较熟悉了,再加油
#include<stdio.h>

int ans[18];

void deal(int x)
{
    if(x==1||x==0)
        return ;
    deal(x-1);
    ans[x]=4*ans[x-1]-ans[x-2];
}

int main()
{
    ans[0]=1;ans[1]=3;
    deal(16);
    int n;
    while(scanf("%d",&n),n!=-1)
    {
        if(n%2!=0)
            printf("0\n");
        else
            printf("%d\n",ans[n/2]);
    }
    return 0;
}


你可能感兴趣的:(poj2663 分治)