zoukankan      html  css  js  c++  java
  • hdu5673 Robot 卡特兰数 / 默慈金数

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5673

    分析:

      这道题是一道裸的默慈金数,比较容易想到的是用卡特兰数来做。不了解的可以先学习一下。

      卡特兰数http://www.cnblogs.com/yaoyueduzhen/p/5456490.html

      默慈金数http://www.cnblogs.com/yaoyueduzhen/p/5456530.html

      记路径长度为nn,那么机器人最多向右走n/2​​⌋步并向左走n/2​​⌋步。

          Ans(n)=C​(n,2i)​​ Catalan(i

      其中 C(n,2i) 表示从n个物品中取2*i个的组合数,Catalan(n)表示第n个卡特兰数,0 <= i <= ⌊n/2​​

      基于n的取值范围,此题可以预处理出1,000,001以内的乘法逆元、卡特兰数。

      每次询问,都可以递推组合数,或者提前一次性预处理好阶乘和阶乘的逆元得到组合数;累加组合数与相应卡特兰数的乘积,得到答案。

      事实上,Ans(n)是第n个默慈金数,利用递推公式可以快速求出。

    卡特兰数代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstring>
     5 
     6 using namespace std;
     7 const long long mod=1000000007;
     8 long long n;
     9 long long ans[1100000],ni[1100000];
    10 
    11 long long power(long long a,long long n,long long m)
    12 {
    13     long long ans=1,tmp=a;
    14     while(n)
    15     {
    16         if(n&1)
    17             ans=ans*tmp%m;
    18         tmp=tmp*tmp%m;
    19         n=n>>1;
    20     }
    21     return ans%m;
    22 }
    23 
    24 void init()
    25 {
    26     ans[0]=1;
    27     ans[1]=1;
    28     for(long long i=1;i<=1000005;i++)
    29         ni[i]=power(i,mod-2,mod)%mod;
    30     for(long long i=2;i<=1000000;i++)
    31         ans[i]=(4*i-2)%mod*ans[i-1]%mod*ni[i+1]%mod;
    32 }
    33 
    34 int main()
    35 {
    36     init();
    37     int T;
    38     scanf("%d",&T);
    39     while(T--)
    40     {
    41         scanf("%lld",&n);
    42         long long res=0,tmp=1;
    43         for(long long  i=0;i*2<=n;i++)
    44         {
    45             res=(res+tmp*ans[i]%mod)%mod;
    46             tmp=tmp*(n-2*i)%mod*(n-2*i-1)%mod*ni[2*i+1]%mod*ni[2*i+2]%mod;
    47         }
    48         cout<<res<<endl;
    49     }
    50     return 0;
    51 }

    默慈金数代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstring>
     5 
     6 using namespace std;
     7 
     8 const long long mod=1000000007;
     9 long long n;
    10 long long ans[1100000];
    11 long long power(long long a,long long n,long long m)
    12 {
    13     long long ans=1,tmp=a;
    14     while(n)
    15     {
    16         if(n&1)
    17             ans=ans*tmp%m;
    18         tmp=tmp*tmp%m;
    19         n=n>>1;
    20     }
    21     return ans;
    22 }
    23 
    24 int main()
    25 {
    26     ans[1]=1;
    27     ans[2]=2;
    28     for(long long i=2;i<=1000000;i++)
    29         ans[i+1]=((2*i+3)%mod*ans[i]%mod+3*i*ans[i-1]%mod)%mod*power(i+3,mod-2,mod)%mod;
    30     int T;
    31     scanf("%d",&T);
    32     while(T--)
    33     {
    34         scanf("%lld",&n);
    35         cout<<ans[n]<<endl;
    36     }
    37     return 0;
    38 }

      

  • 相关阅读:
    零碎知识点
    安卓内存泄漏8种可能
    检测内存泄漏
    kotlin协程
    webview
    安卓各布局优缺点
    splice方法
    angular服务使用
    CSS3的一些笔记
    let、var、const
  • 原文地址:https://www.cnblogs.com/yaoyueduzhen/p/5456602.html
Copyright © 2011-2022 走看看