hdu 5366 排列组合

http://acm.hdu.edu.cn/showproblem.php?pid=5366

Problem Description
![](../../data/images/C613-1001-1.jpg)

ZJiaQ want to become a strong man, so he decided to play the mook jong。ZJiaQ want to put some mook jongs in his backyard. His backyard consist of n bricks that is 1*1,so it is 1*n。ZJiaQ want to put a mook jong in a brick. because of the hands of the mook jong, the distance of two mook jongs should be equal or more than 2 bricks. Now ZJiaQ want to know how many ways can ZJiaQ put mook jongs legally(at least one mook jong).
 

Input
There ar multiply cases. For each case, there is a single integer n( 1 < = n < = 60)
 

Output
Print the ways in a single line for each case.
 

Sample Input
   
   
   
   
1 2 3 4 5 6
 

Sample Output
   
   
   
   
1 2 3 5 8 12

/**
hdu  5366    排列组合
题目大意:ZJiaQ为了强身健体,决定通过木人桩练习武术。ZJiaQ希望把木人桩摆在自家的那个由1*1的地砖铺成的1*n的院子里。
          由于ZJiaQ是个强迫症,所以他要把一个木人桩正好摆在一个地砖上,由于木人桩手比较长,所以两个木人桩之间地砖
          必须大于等于两个,现在ZJiaQ想知道在至少摆放一个木人桩的情况下,有多少种摆法
解题思路:标准题解说是找规律,我智商太低了,只会排列组合,不过也过了。说一下我想法:由于相邻的两个木人之间距离大于1,那么假设现在要插入x个
          木人,那么我们把x-1的木人每个占3个的地板看作一个,那么地板总数就为ans=n-(x-1)*2个地板,答案就是C[ans][x],枚举一下x就可以了。
          对于c数组到60会爆掉long long 不过我们注意到x最大不过21那么就没有问题了,前面的是不会爆的
*/
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;
typedef long long LL;
int n;
LL a[60][60];
void judge()
{
    a[0][0]=1;
    a[1][1]=a[1][0]=1;
    for(int i=2;i<=60;i++)
    {
        a[i][0]=1,a[i][i]=1;
        for(int j=1;j<i;j++)
        {
            a[i][j]=a[i-1][j]+a[i-1][j-1];
        }
    }/*
    for(int i=1;i<=25;i++)
    {
        for(int j=0;j<=i;j++)
        {
            printf("%d ",a[i][j]);
        }
         printf("\n");
    }*/
}
int main()
{
    judge();
    while(~scanf("%d",&n))
    {
        LL sum=0;
        for(int i=1;;i++)
        {
            if((i-1)*3+1>n)break;
            int x=n-2*(i-1);
            sum+=a[x][i];
        }
        printf("%I64d\n",sum);
    }
    return 0;
}


你可能感兴趣的:(hdu 5366 排列组合)