zoukankan      html  css  js  c++  java
  • 【模拟7.27】题(liu_runda的神题)(卡特兰数,组合数)

    考场的SB经验不再分享

    case 0:

    一道组合计数的水题,具体不再讲可以看以前的相似题

    case 1:

    很明显的卡特兰计数,我们把长度为n的序列看成01串

    关于卡特兰计数的详细的讲解

    由此可知我们需要满足从1——n中前缀1的数量不少于前缀0的数量

    case 2:

    满足可以在坐标轴上移动

    设f[i]表示第i步回到原点,我们枚举第j步第一次回到起点

    那么f[i]数组里就不会出现重复,这样可以保证正确性

    同时要再次用到卡特兰数:

       我们发现定义的特殊j是第一次回到起点,但cal中可以多次回到起点

    但我们可以发现只要我们满足在1-j-1满足前缀和>=1即可,这样我们可以

    发现现在序列一部分确定设正方向为1

        1 1 .........0 0

    这样中间部分就又是一个cal,这样我们直接乘cal(j/2-1)即可

    (注意可能j是四个方向,于是乘4)

    case 3:

    同时在两轴及第一象限

    直接用组合数,乘两个方向的cal即可

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<string>
     5 #include<algorithm>
     6 #include<cmath>
     7 #include<stack>
     8 #include<map>
     9 #include<queue>
    10 #define ps push_back
    11 #define MAXN 1000001
    12 #define ll long long
    13 using namespace std;
    14 ll n;
    15 const ll mod=1000000007;
    16 ll jie[MAXN],ni[MAXN],ni_c[MAXN];
    17 ll C(ll x,ll y)
    18 {
    19     if(y>x)return 0;
    20     return jie[x]*ni_c[y]%mod*ni_c[x-y]%mod;
    21 }
    22 ll cal(ll x)
    23 {
    24      return C(x*2,x)*ni[x+1]%mod;
    25 }
    26 ll f[MAXN];
    27 int main()
    28 {
    29       ll orz;
    30       scanf("%lld%lld",&n,&orz);
    31       jie[0]=1;jie[1]=1;
    32       ni[0]=1;ni[1]=1;
    33       ni_c[0]=1;ni_c[1]=1;
    34       for(ll i=2;i<=2*n+10;++i)
    35       {
    36          jie[i]=(jie[i-1]*i)%mod;
    37          ni[i]=((mod-mod/i)*ni[mod%i])%mod;
    38          ni_c[i]=(ni_c[i-1]*ni[i])%mod;
    39       }
    40       ll ans=0;
    41       if(orz==0)
    42       {
    43           for(ll i=0;i<=n;i+=2)
    44           {
    45                ans=(ans+C(n,i)*C(i,i/2)%mod*C(n-i,(n-i)/2))%mod;
    46           }
    47           printf("%lld
    ",ans%mod);
    48       }
    49       else if(orz==1)
    50       {
    51           if(n%2==1)
    52                printf("0
    ");
    53           else
    54                printf("%lld
    ",(C(n,n/2)%mod*ni[n/2+1]%mod+mod)%mod);
    55       }
    56       else if(orz==3)
    57       {
    58           for(ll i=0;i<=n;i+=2)
    59           {
    60                ll th=C(n,i);
    61                if((n-i)%2==1)continue;
    62                ans=(ans+th*cal(i/2)%mod*cal((n-i)/2))%mod;
    63           }     
    64           printf("%lld
    ",ans);
    65       }
    66       else if(orz==2)
    67       {
    68            f[0]=1;
    69            for(ll i=2;i<=n;i+=2)
    70            {
    71                for(ll j=0;j<=i;j+=2)
    72                {
    73                     f[i]=(f[i]+4*f[i-j]*cal(j/2-1))%mod;
    74                }
    75            }
    76            printf("%lld
    ",f[n]);
    77       }
    78 }
    View Code
  • 相关阅读:
    项目管理
    开源视频会议bigbluebutton开发(1)——初始化安装以及配置
    oracle休系统结构
    Tomcat上安装配置Axis
    锁表头
    文件复制三种方法
    程序员技术练级攻略
    Linux (RHEL 5.4)下安装 Oracle 10g R2
    Android 学习资料收集汇总
    WAS61安装调整和应用部署.doc
  • 原文地址:https://www.cnblogs.com/Wwb123/p/11255270.html
Copyright © 2011-2022 走看看