poj2663 分治

来源:互联网 发布:淘宝联盟qq群推广技巧 编辑:程序博客网 时间:2024/06/05 18:24

Tri Tiling
Time Limit: 1000MS Memory Limit: 65536KTotal 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

2812-1

Sample Output

31532131


题意:一个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;}


0 0
原创粉丝点击