zoukankan      html  css  js  c++  java
  • [数论] 洛谷 P1641 生成字符串

    题目描述

    lxhgww最近接到了一个生成字符串的任务,任务需要他把n个1和m个0组成字符串,但是任务还要求在组成的字符串中,在任意的前k个字符中,1的个数不能少于0的个数。现在lxhgww想要知道满足要求的字符串共有多少个,聪明的程序员们,你们能帮助他吗?

    输入输出格式

    输入格式:

    输入数据是一行,包括2个数字n和m

    输出格式:

    输出数据是一行,包括1个数字,表示满足要求的字符串数目,这个数可能会很大,只需输出这个数除以20100403的余数

    输入输出样例

    输入样例#1:
    2 2
    输出样例#1:
    2

    说明

    limitation

    每点2秒

    对于30%的数据,保证1<=m<=n<=1000

    对于100%的数据,保证1<=m<=n<=1000000

    题解

    • 对于这题,我们可以考虑将全部的方案-不合法的方案=合法的方案
    • 先来考虑一下全部的方案,字符串的长度为n+m,在里面放n个1,方案数就是C(n+m,n)
    • 那么怎么求出不合法的情况的方案呢
    • 我们把放0、1当做是在平面直角坐标系上,放1就当做是(+1,+1),放0就当做是(+1,-1)那么当直线到达(x,-1)时,就是不合法的
    • 然后我们把y=-1当做是对称轴,将我们形成的直线对称下来,然后我们可以发现其实就是从(0,-2)开始到达(n+m,n-m)的方案数就是不合法滴
    • 最后的话,答案就是C(n+m,n)-C(n+m,m-1)

    代码

     1 #include <iostream>
     2 #include <cstdio>
     3 #define ll long long
     4 using namespace std;
     5 const ll mo=20100403;
     6 ll n,m,p[2000050],q[2000050];
     7 ll C(ll x,ll y) { return q[x]*p[y]%mo*p[x-y]%mo; }
     8 int main()
     9 {
    10     scanf("%lld%lld",&n,&m),p[0]=p[1]=q[0]=q[1]=1;;
    11     for (ll i=2;i<=n+m;i++) p[i]=(mo-mo/i)*p[mo%i]%mo,q[i]=q[i-1]*i%mo;
    12     for (ll i=2;i<=n+m;i++) p[i]=p[i-1]*p[i]%mo;
    13     printf("%lld",((C(n+m,m)-C(n+m,m-1))%mo+mo)%mo);
    14     return 0;
    15 }
  • 相关阅读:
    怎样运用好ZBrush中的布尔运算
    怎样用好ZBrush 中的映射大师功能
    jvm
    java8 新用法
    entity framework delete table Error 11007:
    'EF.Utility.CS.ttinclude' returned a null or empty string.
    js判断是否绑定了事件。
    线程每5分钟刷新一次
    http请求提交cookie
    javascrip小笔记
  • 原文地址:https://www.cnblogs.com/Comfortable/p/10324738.html
Copyright © 2011-2022 走看看