Codeforces Round #526 C - The Fair Nut and String /// 组合递推

题目大意:

给定原字符序列

找出其中所有子序列满足

1.序列内字符都为a

2.若有两个以上的字符 则相邻两个字符在原序列中两者之间存在字符b

的数量

将整个字符序列用b分开

此时再得到每个b之间a的数量

即 abbgaaba 得到 v[] = { 1 0 2 1 }

此时假设到第 i-1 段 已得到在第 i-1 段内的所有方案数为 ans (长度为1、2、3、... 、i-1)

则在第 i 段时 可由前一段的方案数 和 当前段数量 组合得到ans*v[ i ] (长度为2、3、4、... 、i)

此时第 i 段还可以作为长度为1的方案 即ans=ans*v[ i ] + v[ i ]=(ans+1)*v[ i ]

那么递推即可得到所有方案数

#include <bits/stdc++.h>
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
const int N=1e5+5;
const int mod=1e9+7;
char ch[N];
LL v[N];
int main()
{
    while(~scanf("%s",ch)) {
        int len=strlen(ch);
        memset(v,0,sizeof(v));
        v[0]=1LL;
        int i=0, c=1;
        while(i<len) {
            LL m=0LL;
            while(i<len && ch[i]!=‘b‘) {
                if(ch[i]==‘a‘) m++;
                i++;
            }
            v[c++]=m;
            i++;
        }
        LL ans=0LL;
        for(int j=1;j<=c;j++)
            ans=(ans+(ans+1LL)*v[j]%mod)%mod;
        printf("%I64d\n",ans);
    }

    return 0;
}

原文地址:https://www.cnblogs.com/zquzjx/p/10104289.html

时间: 2024-08-29 02:55:39

Codeforces Round #526 C - The Fair Nut and String /// 组合递推的相关文章

Codeforces Round #526 (Div. 2) C. The Fair Nut and String

C. The Fair Nut and String 题目链接:https://codeforces.com/contest/1084/problem/C 题意: 给出一个字符串,找出都为a的子序列(比如ai,aj,ak)满足以下条件的个数: 1.子序列的索引单增(i<j<k): 2.在原字符串中,若ai=aj=ak=a,那么满足i<=k1<j,j<=k2<k 并且 ak1=ak2=b. 通俗点说,就是找这样的子序列个数:要么单个a,要么每个a之间都有一个b. 题解:

Codeforces Round #526 (Div. 2) D. The Fair Nut and the Best Path

D. The Fair Nut and the Best Path 题目链接:https://codeforces.com/contest/1084/problem/D 题意: 给出一棵树,走不重复的路径,每到一个结点加上其权值,经过一条边减去其权值,路径中途减去后不能出现负数,问怎么选择路径可以让最后得到的最大. 题解: 这题考虑用dp来做. 我们定义dp[u]为走到u点的最大值,注意这里的方向,是走到u点.题目中的意思是路径不能走回头路. 对于一个父节点u,那么我们可以根据走到其儿子结点的最

Codeforces Round #526 (Div. 2) E. The Fair Nut and Strings

E. The Fair Nut and Strings 题目链接:https://codeforces.com/contest/1084/problem/E 题意: 输入n,k,k代表一共有长度为n的多少个字符串.然后给出一个最小字符串s,最大字符串t,满足对于所有的k个字符串有s<=S<=t. 最后求满足条件的k个字符串(自己构造)的不同前缀数量的和. 题解: 这题很巧妙,设dp(i)表示长度为i的前缀的数量和,一开始有dp(1)=0. 后来随着长度的增加,我们每次可以在最后加一个a或者b,

Codeforces Round #526 (Div. 1)

毕竟是上紫之后的第一场div1,还是太菜了啊,看来我要滚回去打div2了. A. The Fair Nut and the Best Path 这题本来是傻逼贪心dfs,结果我越写越麻烦,然后就只有150了.. #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<set> #include<map> #include<ve

Codeforces Round #548 (Div. 2) C dp or 排列组合

https://codeforces.com/contest/1139/problem/C 题意 一颗有n个点的树,需要挑选出k个点组成序列(可重复),按照序列的顺序遍历树,假如经过黑色的边,那么这个序列就是好的,问有多少个好的序列 题解 黑边不连,红边连,假如两个点不在同一并查集,那么一定经过黑边 定义\(dp[i][j][k]\)为选择前i个点,起始点为j,是否已经经过黑边(k)的方案数 \(dp[i-1][j][0]*(n-N[fin(j)])+dp[i-1][j][1]*n - > dp

Codeforces Round #354 (Div. 2) C. Vasya and String

题目大意:有一个(a|b)^N的由a和b构成的长度为N的字符串,允许修改其中k位.问能构成的最长的全为a或全为b的子串的长度最长为多少. 思路,用两个队列分别保存前K+1个a和b的位置,以i为结尾的最长的子串的长度就是i减去队列头元素的值. #include <iostream> #include <cstdio> #include <memory.h> #include <queue> using namespace std; int main(int a

Codeforces Round #297 (Div. 2)B Pasha and String

B. Pasha and String time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Pasha got a very beautiful string s for his birthday, the string consists of lowercase Latin letters. The letters in the

Codeforces Round #445 div.2 D. Restoration of string 乱搞

D. Restoration of string 题意:给你n个字符串,让你构造一个终串,使得这n个字符串都是终串的最小频繁子串,如果不存在输出NO.  最频繁子串:出现次数最多的子串 tags: 直接暴力怼?? #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a;

Codeforces Round #501 (Div. 3) B Obtaining the String

翻译 给你两个字符串\(s\)与\(t\),你每次可以交换字符串\(s\)种相邻两个字符,请你输出字符串\(s\)变成\(t\)的步骤(如果输出\(k\),代表交换了\(k\)与\(k+1\)),如果有多组解,随意输出一种即可. 思路 这道题一开始考虑复杂了,导致我发奋图强到\(11:40\)才\(A\)掉,我\(12:00\)必须睡觉因为明天有课\(www\). 实际不难,这题是\(SPJ\),我是这么想的:我们都知道任意\(1\)个字符可以通过交换相邻的两个字符来跑遍整个字符串. 进而可以得