SHU1919 Running Man,Bob(那罗延数)

来源:互联网 发布:seo入门博客 编辑:程序博客网 时间:2024/05/17 06:33

Description

Bob很喜欢锻炼身体,也很喜欢跑步。

但他在跑步的时候总是控制不好自己跑步的方向,每一步都会跑到别的跑道上。

假设Bob正在跑一条直线跑道,从左往右依次是1号跑道,2号跑道,3号跑道……

如此类推,为了让Bob更自由,总共有无限条跑道!Bob需要跑2*n步才能到达终点,但是正如上面所说,Bob每跑一步都会偏离原来的跑道,也就是会蹿到相邻的跑道,当然Bob是不会跑到1号跑道的左边去的。Bob一定是从1号跑道开始跑的,同样,最后必须回到1号跑道到达终点。已知Bob在这过程之中,一共调整了2*k-1次方向,那么请问Bob一共有多少种方案来跑完这2*n步呢?(两种方案视为不同当且仅当两种方案的某一步所在的跑道不同)

ps:若当前Bob跑的时候在往右边的跑道偏,则在他刻意去调整方向之前,他将一直朝右边偏。

Input

第一行为一个整数T,表示有T组数据(T≤100)

接下来的T行的之内每行包含两个整数n,k(1≤k≤n≤20)

Output

每行输出一个数,即方案数

Sample Input

2
2 1
4 2

Sample Output

1
6

HINT



对于第一组样例Bob的方案为1-2-3-2-1


对于第二组样例,Bob的方案为:


1-2-3-2-3-4-3-2-1;1-2-3-4-3-4-3-2-1;


1-2-3-4-3-2-3-2-1;1-2-1-2-3-4-3-2-1;


1-2-3-2-1-2-3-2-1;1-2-3-4-3-2-1-2-1;


答案较大,请使用long long类型



这道题用了Narayanna number

ACMer只需要知道怎么用就好了。

以下解释来自Wiki

Formula


Combinatorial interpretations

An example of a counting problem whose solution can be given in terms of the Narayana numbersN(nk), is the number of expressions containingn pairs of parentheses, which are correctly matched and which containk distinct nestings. For instance,N(4, 2) = 6 as with four pairs of parentheses six sequences can be created which each contain two times the sub-pattern '()':

在由n对"(“、”)"组成的字符串中,共有k对“(“与”)”相邻,这样的字符串一共有N(n,k)个。例如n=4,k=2时,N(n,k)=6,分别为

()((()))  (())(())  (()(()))  ((()()))  ((())())  ((()))()

The sum of the rows in this triangle equal the Catalan Numbers:

N(n,1) + N(n,2) + N(n,3) + \cdots + N(n,n) = C_n.

Numerical values

The first eight rows of the Narayana triangle read:

k =      1   2   3   4   5   6   7   8n = 1    1    2    1   1    3    1   3   1    4    1   6   6   1    5    1  10  20  10   1    6    1  15  50  50  15   1    7    1  21 105 175 105  21   1    8    1  28 196 490 490 196  28   1

用到这道题还是可以理解的,首先向左的步数和向右的步数一样多,一直保持着向左(可以用“)”理解)的数目不能比向右(可以用“(”理解)的数目多,直到最后达到相等。

代码如下:

#include<iostream>using namespace std;int main(void){    int t,n,k;    long long C[21][21];    C[0][0]=C[1][0]=C[1][1]=1;    for(int i=2;i<=20;i++)    {        C[i][0]=C[i][i]=1;        for(int j=1;j<i;j++)            C[i][j]=C[i-1][j]+C[i-1][j-1];    }    cin>>t;    while(t--)    {        cin>>n>>k;        cout<<C[n][k]*C[n][k-1]/n<<endl;    }    return 0;}


0 0
原创粉丝点击