hdu 1131 Count the Trees

来源:互联网 发布:见什么知什么 编辑:程序博客网 时间:2024/06/01 09:39

 本题为经典的卡特兰数问题。在不考虑顺序(即字母顺序),将结点编号为0~n-1;任取一个节点k作根节点,从而衍生出两个子问题f(k-1)和f(n-k),有f(k-1)*f(n-k)棵树;则

   f(n)=f(0)(n-1)+f(1)f(n-1)+.......+f(n-1)*f(0);符合卡特兰数的递推公式。详见点击打开链接。有该递推公式可以推出f(n)=f(n-1)*(4n-2)/(n+1);好!现在卡特兰数的问题解决了,来看

   加入字母顺序以后,这可以看成已经准备好了n个位置,现在要按排座位,这是个排序问题,排序总数为n!种!所以数的数量就等于:f(n)*n!;别!别以为现在就解决问题了。来看看题目吧!n可以达到100。f(100)的位数可以达到60~80!具体自己去数吧!而100!的位数可以达到160左右。任何数值类型都不能容纳!所以又是个高精度问题。本想

先算出1-100的卡特兰数,在算出1-100的阶乘,再相乘!但很不理想!两个都是大数。很复杂!还没涉及!所以改成h(n)=h(n-1)*n*(4n-2)/(n+1)(h(n)为数的数量).这里乘法和除法要分开进行。


#include <algorithm>#include <iostream>#include <cstdio>#include <cstdlib>#include <string>#include <cstring>#include <cmath>#include <stack>#include <queue>#include <vector>#include <map>using namespace std;#define INF 0x3f3f3f3f#define maxn 20010#define g 9.8int a[110][1100];void Catalan(){    int yu,len = 1;    a[2][0]=1;    a[2][1]=2;    a[1][0]=1;    a[1][1]=1;    for(int i = 3; i <= 100; i++)    {        yu = 0;        for(int j = 1; j <= len; j++)        {            int t = a[i-1][j]*(4*i-2)+yu;            yu = t / 10;            a[i][j] = t % 10;        }        while(yu)        {            a[i][++len] = yu % 10;            yu /= 10;        }        for(int j = len; j >= -1; j--)        {            int t = a[i][j] + yu * 10;            a[i][j] = t / (i+1);            yu = t % (i+1);        }        while(!a[i][len])            len--;    }    for(int i = 2; i <= 100; i++)    {        for(int k = 2; k <= i; k++)        {            yu = 0;            for(int j = 1; j <= len; j++)            {                int t = a[i][j]*k+yu;                yu = t / 10;                a[i][j] = t % 10;            }            while(yu)            {                a[i][++len] = yu % 10;                yu /= 10;            }            while(!a[i][len])                len--;        }        a[i][0] = len;    }}int main(){    int n;    Catalan();    while(scanf("%d",&n) && n)    {        for(int i = a[n][0]; i > 0; i--)            printf("%d",a[n][i]);        printf("\n");    }    return 0;}


0 0
原创粉丝点击