CodeForces - 1084C The Fair Nut and String(DP)
题目意思就是给你一个字符串,然后要问你一种子序列的种数有多少?然后这种子序列的定义是这样的:子序列是递增的字符串s下标,然后对于子序列里的每个下标,要求该下标对应的s里的字符是'a',然后要求子序列里每一个下标和它后面的一个下标之间存在一个下标j,s[j]是‘b'.
思路:举几个例子就可以发现递推的规律,我们把s里连起来的’a'视为一块整体,'b'也一样 。1. 字符串s=a...a s里只有一块a,假设长度为len1,那么这种情况方案数就是dp[1]=len1 2.字符串s=a...ab...ba..a 这时s里有2块a,假设第一块是len1,第二块是len2,可以这样想,第二种情况就是在第一种情况的后面多加了一块a,那么因为这个长度为len2的a块的出现而增加的方案数我们算出来,然后加上第一种情况的方案数就是第二种情况的方案数了,长度为len2的a块的出现而增加的方案数计算如下:首先从len2个a里面可以取一个a的下标出来组成一个长度为1的子序列,方案数是len2,然后从len2个a里面可以取一个a的下标出来和前面的a块组成的长度为1的子序列拼接起来就可以得到长度为2的子序列的个数,方案数就是len2*(前面的a块组成的长度为1的子序列的个数),综合起来说增加的方案数就是(dp[1]+1)*len2,然后dp[2]=dp[1]+(dp[1]+1)*len2,这个就是递推式了。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod=1e9+7;
const int maxn=1e5+10;
char s[maxn];
int main()
{
ll ans=0,cnt=0,len;
scanf("%s",s);
len=strlen(s);
for(int i=0;i<len;i++)
{
if(s[i]=='a')
{
cnt++;
}
else
if(s[i]=='b')
{
ans=(ans+(ans+1)%mod*cnt%mod)%mod;
cnt=0;
}
}
ans=(ans+(ans+1)%mod*cnt%mod)%mod;
cout<<ans<<endl;
return 0;
}