【HDU】2067-小兔的棋盘

                        Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
                                          Total Submission(s): 12794    Accepted Submission(s): 6399


 

Problem Description

小兔的叔叔从外面旅游回来给她带来了一个礼物,小兔高兴地跑回自己的房间,拆开一看是一个棋盘,小兔有所失望。不过没过几天发现了棋盘的好玩之处。从起点(0,0)走到终点(n,n)的最短路径数是C(2n,n),现在小兔又想如果不穿越对角线(但可接触对角线上的格点),这样的路径数有多少?小兔想了很长时间都没想出来,现在想请你帮助小兔解决这个问题,对于你来说应该不难吧!

 

 

Input

每次输入一个数n(1<=n<=35),当n等于-1时结束输入。

 

 

Output

对于每个输入数据输出路径数,具体格式看Sample。

 

 

Sample Input

 

1 3 12 -1

 

 

Sample Output

 

1 1 2 2 3 10 3 12 416024

 

 

Author

Rabbit

 

 

Source

RPG专场练习赛

 

 

Recommend

lcy   |   We have carefully selected several similar problems for you:  2064 2065 1133 2068 1267 

 

思路:可以用dp来做(在下面),也可以用卡特兰数来做,说一下卡特兰数吧,

n*n的方格地图中,从一个角到另外一个角,不跨越对角线的路径数为h(n).例如, 4×4方格地图中的路径有:

这道题目可以理解为 横着走的和竖着走的 组成了卡特兰数的第一个递推公式:

                                                h(n)=h(0)*h(n-1)+h(1)*h(n-2)+...+h(n-1)*h(0).

算式运行中从不存在大于n的情况,所以,算的是下面的那一块,

还有就是这个棋盘并不只有下面的部分,上面的部分和这个一样的,对称着来。

卡特兰数公式及例题应用总结,可以看一下这个总结中的例题9,和这个一样的,

别忘了 long long.....

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#define N 40
#define ll long long          
using namespace std;
ll f[N]; //不开long long 是错误的。。。。
int main()
{
    f[0]=f[1]=1;
    for(int i=2;i<=35;i++)
    {
        for(int j=0;j<=i-1;j++)
            f[i]+=f[j]*f[i-j-1];
    }
    int num=1,n;
    while(cin>>n&&n!=-1)
    {
        printf("%d %d %lld\n",num++,n,f[n]*2);
    }
    return 0;
}

还可以用递推的方法来做,

 图源

思路就这样,基本就这么来的,

递推公式:f[i][j]=f[i-1][j]+f[i][j-1];

不过这个也是算的一半,另一半也差不多的,就是这个的话,不会有大于i的情况,

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#define N 40
#define ll long long
using namespace std;
ll f[N][N];
int main()
{
    for(int i=0;i<=35;i++)
        f[i][0]=1;
    for(int i=0;i<=35;i++)
        for(int j=1;j<=i;j++)
            f[i][j]=f[i-1][j]+f[i][j-1];
    int num=1,n;
    while(cin>>n&&n!=-1)
    {
        printf("%d %d %lld\n",num++,n,f[n][n]*2);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值