• 51nod1313 完美串


    一个N长的字符串S(N<=3000),只由'R','G','B'三种字符组成,即串中不存在除了这3个字符以外的其他字符。字符串S的子串substr(L,R)指S[L]S[L+1]S[L+2]..S[R]构成的字符串,其中0<=L<=R<N。称一个字符串为“完美串”,当且仅当该串中存在K个连续的'G'字符。问,存在多少个不同的四元组(a,b,c,d)满足substr(a,b)+substr(c,d)是完美串,其中,0 <= a <= b < c <= d < N。
    说明:字符串A和字符串B的+运算指将B连在A的后面,即A+B=AB,如“RRG”+“GBB”=“RRGGBB”。
     
    例如:S="GRG",K=2,因为S中一共就2个'G',而要求K=2,所以只有1个四元组(0,0,2,2)成立,即"G"+"G"="GG".
    Input
    第一行一个整数K,1<=K<=3000.
    第二行一个字符串S,1<=len(S)<=3000,且只由'R','G','B'三种字符组成。
    Output
    一个整数,即不同的四元组(a,b,c,d)的个数。

    容斥+dp,

    ans=([a,b]存在k个连续的'G',[c,d]任意的方案数)+([c,d]存在k个连续的'G',[a,b]任意的方案数)-([a,b],[c,d]都存在k个连续的'G'的方案数)+([a,b],[c,d]都不存在k个连续的'G',但拼起来之后存在k个连续的'G'的方案数)

    #include<cstdio>
    #include<cstring>
    char s[3003];
    int n,k;
    long long ans=0;
    int ls[3003],rs[3003];
    short cl[3003][3003],cr[3003][3003],cs[3003][3003];
    int l1[3003][3003],r1[3003][3003];
    int max(int a,int b){return a>b?a:b;}
    int C(int x){return x*(x+1)/2;}
    int main(){
        scanf("%d%s",&k,s+1);
        n=strlen(s+1);
        for(int i=1;i<=n;++i)if(s[i]!='G')s[i]=0;
        for(int i=1;i<=n;++i)if(s[i])cs[i][i]=cl[i][i]=cr[i][i]=1;
        for(int d=1;d<n;++d)for(int l=1,r=1+d;r<=n;++l,++r){
            if(s[r])cl[l][r]=cl[l][r-1]+1;
            if(s[l])cr[l][r]=cr[l+1][r]+1;
            cs[l][r]=max(max(cs[l][r-1],cs[l+1][r]),max(cl[l][r],cr[l][r]));
        }
        for(int i=1;i<=n;++i){
            for(int j=1;j<=i;++j)if(cs[j][i]>=k)++ls[i];
            for(int j=i;j<=n;++j)if(cs[i][j]>=k)++rs[i];
        }
        for(int i=n;i;--i)rs[i]+=rs[i+1];
        for(int i=1;i<n;++i)ans+=1ll*ls[i]*C(n-i)+1ll*rs[i+1]*i-1ll*ls[i]*rs[i+1];
        for(int i=1;i<=n;++i)for(int j=i;j<=n;++j){
            if(cs[i][j]<k&&cs[i][j]){
                if(cl[i][j])++l1[j][cl[i][j]];
                if(cr[i][j])++r1[i][cr[i][j]];
            }
        }
        for(int i=n;i;--i)for(int j=1;j<k;++j)r1[i][j]+=r1[i+1][j];
        for(int i=1;i<=n;++i)for(int j=k-1;j;--j)r1[i][j]+=r1[i][j+1];
        for(int i=1;i<n;++i)for(int j=1;j<k;++j)ans+=1ll*l1[i][j]*r1[i+1][k-j];
        printf("%lld",ans);
        return 0;
    }
    一个N长的字符串S(N<=3000),只由'R','G','B'三种字符组成,即串中不存在除了这3个字符以外的其他字符。字符串S的子串substr(L,R)指S[L]S[L+1]S[L+2]..S[R]构成的字符串,其中0<=L<=R<N。称一个字符串为“完美串”,当且仅当该串中存在K个连续的'G'字符。问,存在多少个不同的四元组(a,b,c,d)满足substr(a,b)+substr(c,d)是完美串,其中,0 <= a <= b < c <= d < N。
    说明:字符串A和字符串B的+运算指将B连在A的后面,即A+B=AB,如“RRG”+“GBB”=“RRGGBB”。
     
    例如:S="GRG",K=2,因为S中一共就2个'G',而要求K=2,所以只有1个四元组(0,0,2,2)成立,即"G"+"G"="GG".
    Input
    第一行一个整数K,1<=K<=3000.
    第二行一个字符串S,1<=len(S)<=3000,且只由'R','G','B'三种字符组成。
    Output
    一个整数,即不同的四元组(a,b,c,d)的个数。
  • 相关阅读:
    BackgroundWorker
    Devexpress 10
    Winform常用控件的使用(一)
    Composite UI Application Block(CAB)
    HTML CSS简单总结
    C# JSON字符串序列化与反序列化常见模型举例
    HTML 调用iscroll.js主要事项
    HTML5 Socket通信
    Webservice加上SoapHeader验证方式
    动态调用Webservice 支持Soapheader身份验证(转)
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5858152.html
Copyright © 2020-2023  润新知