• hdu 4828 Grids (卡特兰数)


    题意:度度熊最近很喜欢玩游戏。这一天他在纸上画了一个2行N列的长方形格子。他想把1到2N这些数依次放进去,但是为了使格子看起来优美,他想找到使每行每列都递增的方案。不过画了很久,他发现方案数实在是太多了。度度熊想知道,有多少种放数字的方法能满足上面的条件?

    思路:

             思路基本没有,看的其他人的题解才知道是应用卡特兰数的题

             我们假设0代表这个数放在第一排,1代表这个数放在第二排,如果序列00001111

             就是  1 2 3 4

                      5 6 7 8 

             序列01010101  就是 1 3 5 7

                                            2 4 6 8

              这个问题就转化成有几种满足题目条件的01序列,通过观察发现每个位置之前0的个数大于等于1的个数

              如果把0看成入栈,1看成出栈,

              这个问题变转化成n个数的入栈的出栈次序的种类数,也就是卡特兰数

    代码:

    #include <iostream>
    #include <cstdio>
    #define ll long long
    #define mod 1000000007
    using namespace std;
    const int maxn=2000000;
    ll fact[maxn+5];
    ll inv[maxn+5];
    
    ll qmod(ll a,ll b)
    {
        ll ans=1;
        a=a%mod;
        while(b)
        {
            if(b&1)
            {
                ans=(ans*a)%mod;
            }
            b=b/2;
            a=(a*a)%mod;
        }
        return ans;
    }
    
    ll init()
    {
        fact[0]=1;inv[0]=1;
        for(ll i=1;i<=maxn;i++)
        {
            fact[i]=(fact[i-1]*i)%mod;
            inv[i]=qmod(fact[i],mod-2);
        }
    }
    
    ll catalan(ll n)
    {
        return (((((fact[2*n]*inv[n])%mod)*inv[n])%mod)*qmod(n+1,mod-2))%mod;
    }
    
    int main()
    {
        int t,cas=1;
        init();
        cin>>t;
        while(t--)
        {
            ll n;
            scanf("%lld",&n);
            printf("Case #%d:
    %lld
    ",cas++,catalan(n));
        }
        return 0;
    }
  • 相关阅读:
    Kruskal
    克鲁斯卡尔
    克鲁斯卡尔
    实践是检验真理的唯一标准 脱壳篇02
    Kruskal
    克鲁斯卡尔算法讲解
    实践是检验真理的唯一标准 脱壳篇02
    最小生成树(普里姆算法) 数据结构和算法62
    克鲁斯卡尔算法讲解
    最小生成树(普里姆算法) 数据结构和算法62
  • 原文地址:https://www.cnblogs.com/simplekinght/p/7090277.html
Copyright © 2020-2023  润新知