hdu 5366 The mook jong【递推】【思维】

来源:互联网 发布:英汉翻译软件语音 编辑:程序博客网 时间:2024/05/17 00:57

The mook jong

 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 65536/65536 K (Java/Others)
问题描述
ZJiaQ为了强身健体,决定通过木人桩练习武术。ZJiaQ希望把木人桩摆在自家的那个由1*1的地砖铺成的1*n的院子里。由于ZJiaQ是个强迫症,所以他要把一个木人桩正好摆在一个地砖上,由于木人桩手比较长,所以两个木人桩之间地砖必须大于等于两个,现在ZJiaQ想知道在至少摆放一个木人桩的情况下,有多少种摆法。
输入描述
输入有多组数据,每组数据第一行为一个整数n(1 < = n < = 60)
输出描述
对于每组数据输出一行表示摆放方案数
输入样例
123456
输出样例
1235812

分治思想:将这么个问题分解成这样的问题:当放一个木人的时候是怎么放的,当放两个木人的时候是怎么放的、当放三个木人的时候是怎么放的................
当放一个木人的时候,所有格子都算一种方案:C(n,1)【排列组合,Cn取1】
当放两个木人的时候,其中有限制条件,两个木人桩之间地砖必须大于等于两个,然后呢,我们在纸上比比画画,发现其实就是相当于n个地砖去掉两个相连的地砖,然后剩下的地方从中挑两个地方放木人桩,其实就相当于C(n-2,2);
依次类推,当放三个木人的时候,其实就相当于C(n-4,3);
然后我们每个情况都枚举出来,加在一起,就知道了当前n的时候,能有多少种放的方法、因为这里我的代码求C(M,N)的时候C(40,11)就爆LONG LONG 了,所以最后一个数据n=60的时候是个负的值,所以这里我从网上盗了一个n=60的时候的数据、【懒得用计算器手算了->.->】
最后上AC代码:【注意数据比较大,变量要用LL】
#include<stdio.h>#include<string.h>using namespace std;const int MAXN = 100; // 组合上限long long int  c[MAXN][MAXN];    // 组合数long long int output[61];void GetGroup(){    c[0][0] = c[1][0] = c[1][1] = 1;    for (int i=2; i<MAXN; ++i)    {        c[i][0] = 1;        for (int j=1; j<=i; ++j)            c[i][j] = (c[i-1][j] + c[i-1][j-1]);  // 求模,防止结果过大    }    return ;}int main(){    GetGroup();    for(int i=1;i<=59;i++)    {        long long int sum=0;        sum+=i;        for(int j=1;j<=20;j++)        {            if(i-j*2>=j+1)            {                sum+=c[i-j*2][j+1];            }        }        output[i]=sum;       // printf("%I64d\n",sum);    }    output[60]=11990037125;    int n;    while(~scanf("%d",&n))    {        printf("%I64d\n",output[n]);    }}




0 0
原创粉丝点击