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

23 篇文章 0 订阅

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)
输出描述
对于每组数据输出一行表示摆放方案数
输入样例
1	
2
3
4
5
6
输出样例
1
2
3
5
8
12

分治思想:将这么个问题分解成这样的问题:当放一个木人的时候是怎么放的,当放两个木人的时候是怎么放的、当放三个木人的时候是怎么放的................
当放一个木人的时候,所有格子都算一种方案: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]);
    }
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值