zoukankan      html  css  js  c++  java
  • SZOJ 177 生

    【问题描述】

    现定义, 对于一个 01 字符串的一次修改是, 若该字符串的后两位为 00 , 则将这两位修改为 1 ; 否则, 修改为 0.

    求满足不断修改到只剩一位之后为 g 的所有有 n 个 00 , m 个 1 的 01 字符串的个数模 10^9+7 的值.

    例如, 01011 -> 0100 -> 011 -> 00 -> 1
    【输入格式】

    共一行, 包含三个整数, n , m , g .

    【输出格式】

    输出一个整数. 如题所述.

    【样例输入】

    2 2 0
    【样例输出】

    4
    【数据规模】

    对于 20% 的数据,n,m≤5。

    对于 100% 的数据:0≤n,m≤10^5 , n+m≥1 , 0≤g≤1。

    我们先来讨论长度为n为1的串

    当n%2==0  最终一定是得到0的

    当n%2==1 最终一定是得到1的

    对于全为1的串只有这两种合法情况

    那么对于由0和1组成的串

    我们先钦定一种特殊情况

    前为n个连续0,后为m个连续1的钦定串,如下

    00000.....011111....111

    那么对于从右往左的最后一个1,称其为关键位置,

    那么确定了这个位置,则次位置往右的所有1,判断其长度,找到长度对应的合法情况,

    而对于位置及位置左边的1,将其插入m个0中,就是当前枚举长度合法的情况总数,累计组合数求解即可

    #include<iostream>
    #include<cstdlib>
    #include<cstdio>
    #include<algorithm>
    #define ll long long
    using namespace std;
    int n,m,g;
    long long ans,f[1000001];
    const long long mod=1000000007;
    inline long long qwr(ll x ,ll y){
        ll ret=1;
        while(y){
            if(y&1) ret=(ret*x)%mod;
            x=(x*x)%mod;
            y>>=1;
        }
        return ret;
    }
    inline long long C(ll x,ll y){return (f[x]*qwr(((f[y]*f[x-y])%mod),mod-2))%mod;}
    inline void Jimmy(){
        scanf("%d%d%d",&n,&m,&g);
        f[0]=1;
        for(int i=1;i<=n+m;i++)
            f[i]=(f[i-1]*i)%mod;
        for(int i=m;i<=n+m;i++)
            if(((n+m-i)&1)==0 && (g==0) || ((n+m-i)&1) && (g==1))
                ans=(ans+(C((ll)i-1,(ll)i-m)%mod))%mod;
        printf("%lld
    ",ans);
    }
    int main(){
        Jimmy();
        return 0;
    }
    View Code
  • 相关阅读:
    算法---递归及尾递归
    ScheduledThreadPoolExecutor之remove方法
    数据结构---队列及简单实现有界队列
    数据结构---栈及四则运算实现
    数据结构---链表及约瑟夫环问题带来的思考
    数据结构---数组
    时间复杂度和空间复杂度
    Redis缓存设计与性能优化
    Springboot+ELK实现日志系统简单搭建
    Docker学习笔记(三):Dockerfile及多步骤构建镜像
  • 原文地址:https://www.cnblogs.com/JimmyC/p/6528345.html
Copyright © 2011-2022 走看看