• luogu P1641 [SCOI2010]生成字符串


    传送门

    代码极短

    (O(n^2))dp是设(f_{i,j,k})表示前(i)位,放了(j)个1,后面还可以接着放(k)个0的方案,转移的话,如果放0,(k)就要减1,反之放了1,后面可以多放一个0,所以(k)加1,即$$f_{i+1,j,k-1}+=f_{i,j,k}$$$$f_{i+1,j+1,k+1}+=f_{i,j,k}$$

    这样子还是不好优化,,,

    我们可以把问题抽象化,把这个放字符过程转化为从平面直角坐标系的((0,0))走到((n,m)),其中放1相当于横坐标+1,放0相当于纵坐标+1,因为要求任何一个前缀中1个数大于等于0个数,也就是走的过程中不能经过((x,x+1)),也就是不能碰到直线(y=x+1).这是个经典问题,答案为(inom{n+m}{m}-inom{n+m}{m-1}).至于为什么,这里有一道类似的

    // luogu-judger-enable-o2
    #include<bits/stdc++.h>
    #define LL long long
    #define il inline
    #define re register
    #define db double
    #define eps (1e-5)
    
    using namespace std;
    const int N=1000000+10,mod=20100403;
    il LL rd()
    {
        re LL x=0,w=1;re char ch;
        while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
        return x*w;
    }
    LL n,m,jc[N<<1];
    il LL ksm(LL a,LL b)
    {
      LL an=1;
      while(b)
        {
          if(b&1) an=(an*a)%mod;
          a=(a*a)%mod;
          b>>=1;
        }
      return an;
    }
    
    int main()
    {
      n=rd(),m=rd();
      jc[0]=1;
      for(int i=1;i<=n+m;i++) jc[i]=(jc[i-1]*i)%mod;
      printf("%lld
    ",((jc[n+m]*ksm(jc[n],mod-2)%mod*ksm(jc[m],mod-2)%mod-jc[n+m]*ksm(jc[n+1],mod-2)%mod*ksm(jc[m-1],mod-2)%mod)%mod+mod)%mod);
      return 0;
    }
    
    
  • 相关阅读:
    window.history 和 DWZ 框架
    Ztree 随笔记
    eval的对于验证数学公式的用处
    lodop打印控件一点记录
    font和lineheight冲突。
    Windows CMD命令大全
    centos 下安装pip pip3
    Linux访问windows共享文件夹
    数据库主从和读写分离的配置和使用方法
    centos7 nginx+php7yum安装
  • 原文地址:https://www.cnblogs.com/smyjr/p/9740307.html
Copyright © 2020-2023  润新知