zoukankan      html  css  js  c++  java
  • bzoj 4403 序列统计——转化成组合数的思路

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4403

    先说说自己的想法吧。

    设f[ i ][ j ]表示当前在倒数第 i 个位置,当前和后面的最高的列(最大的数)是 j 的方案数。

    考虑当前填0,则用f[ i-1][ j ]转移;当前填1,相当于把后面的都消去最底下一行,用f[ i-1 ][ j-1 ]转移。

    所以f[ i ][ j ]=∑(k:0~j)f[ i-1 ][ k ]。然后矩阵优化。

    结果发现 j 的范围达到1e9,也就是要建1e9*1e9的矩阵。于是萎了。

    看TJ:https://blog.csdn.net/Clove_unique/article/details/68491395

    关键的思路可能在于发现随便选即可,之后排序。

    没错,不用 +i 转换成升序也是可以这样转化的。很经典。

    C( )里必须判断 if(n<m)return 0; !因为n%mod,m%mod时很容易传进n<m的参数!

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define ll long long
    using namespace std;
    const int mod=1e6+3;
    int T,n,m,l,r,jc[mod+5],jcn[mod+5];
    int pw(int x,int k)
    {
      int ret=1;while(k){if(k&1)ret=(ll)ret*x%mod;x=(ll)x*x%mod;k>>=1;}return ret;
    }
    void init()
    {
      jc[0]=1;
      for(int i=1;i<mod;i++)jc[i]=(ll)jc[i-1]*i%mod;
      jcn[mod-1]=pw(jc[mod-1],mod-2);
      for(int i=mod-2;i>=0;i--)jcn[i]=(ll)jcn[i+1]*(i+1)%mod;
    }
    int C(int n,int m)
    {
      if(n<m)return 0;//////
      return (ll)jc[n]*jcn[m]%mod*jcn[n-m]%mod;
    }
    int lucas(int n,int m)
    {
      if(!m)return 1;if(n<mod&&m<mod)return C(n,m);
      return (ll)lucas(n/mod,m/mod)*C(n%mod,m%mod)%mod;
    }
    int main()
    {
      init();
      scanf("%d",&T);
      while(T--)
        {
          scanf("%d%d%d",&n,&l,&r);m=r-l+1;
          printf("%d
    ",(lucas(n+m,m)-1+mod)%mod);
        }
      return 0;
    }
  • 相关阅读:
    Django REST framework 1
    爬虫基本原理
    QueryDict对象
    Django组件ModelForm
    MongoDB
    Algorithm
    BOM
    CSS
    Vue
    AliPay
  • 原文地址:https://www.cnblogs.com/Narh/p/9261729.html
Copyright © 2011-2022 走看看