Sample Input
1
3
12
-1
1 1 2
2 3 10
3 12 416024
这题非常简单,有两种做法:
1.DP递推:
由于某一个格子只能在通过左边或者上面的格子后才能到达(只考虑右半边),所以除了对角线上的格子外,到达某一个格子(i,j)的路径情况为dp[i][j]=dp[i-1][j]+dp[i][j-1];而要到达对角线上的格子(i,i)则必须到达该格子的上面一个格子:dp[i][i]=dp[i-1][i];
代码:
#include
#include
#include
#include
using namespace std;
long long str[40][40];
int main()
{
int i, j, n;
for (j = 0; j <= 35; j++)
str[0][j] = 1;
for (i = 1; i <= 35; i++)
{
str[i][i] = str[i - 1][i];
for (j = i + 1; j <= 35; j++)
str[i][j] = str[i - 1][j] + str[i][j - 1];
}
i = 1;
while (scanf("%d", &n) != EOF&&n != -1)
{
printf("%d %d %lld\n", i++, n, 2 * str[n][n]);
}
return 0;
}
2.卡特兰数
这题的数据的规律符合卡特兰数的特点,而重点是符合卡特兰数的证明。
在《组合数学》(Richard A.Brualdi著)的第8章《特殊计数序列》中,首先介绍了卡特兰数:
(在该题中)若将向右走一格设置为+1,向下走一格设置为-1,那么n个+1和n个-1构成的2n项 a1,a2,……,a2n,其从开始到某一个位置k(k<=2n)都满足a1+a2+……+ak>=0的数列的个数等于第n个卡特兰数Cn=1/(n+1)c(2n,n)(组合中的c)。
这是可以运用卡特兰数的标志,即只有两种数据情况下,n个第一种元素与n个第二种元素构成2n项并满足上述特点,即符合卡特兰数的规律。
而卡特兰数则是
证明(以该题为例):
在n个+1和n个-1构成的2n项中,若不考虑到某一个位置为止数列和大于0的条件下,共有c(2n,n)种情况,设其中符合上述条件的数列为An,不符合上述条件的数列为Un,则An+Un=c(2n,n)。
在含n个+1和n个-1的Un中,由于数列不符合条件,则存在一个最小的k使直到k位置为止a1+……+ak=-1,则a1+……+ak-1=0,ak=-1,且k一定为奇数。现在把1到k项的符号反转,即ai=-ai,则生成了n+1个+1和n-1个-1的序列,而在该新序列中,有+1个数刚好超过-1个数的最小位置,从1到该位置将符号反转,即可生成原序列——说明这个过程是可逆的,即有多少个符合条件的含n+1个+1和n-1个-1的序列,就有多少个不符合条件的含n个+1和n个-1的序列,则Un=c(2n,n+1),则An=c(2n,n)-c(2n,n+1),化简得An=1/(n+1)c(2n,n)。