码迷,mamicode.com
首页 > 其他好文 > 详细

luogu P1641 [SCOI2010]生成字符串

时间:2018-10-04 09:24:05      阅读:120      评论:0      收藏:0      [点我收藏+]

标签:enable   ==   mat   problem   main   str   bin   字符串   转化   

传送门

代码极短

\(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\).这是个经典问题,答案为\(\binom{n+m}{m}-\binom{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\n",((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;
}

luogu P1641 [SCOI2010]生成字符串

标签:enable   ==   mat   problem   main   str   bin   字符串   转化   

原文地址:https://www.cnblogs.com/smyjr/p/9740307.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!