1426F
2k分的dp哦
给一个带?的字符串,?可以为a,b,c。找有多少个abc子序列(不是找最大的那个子序列)
dp[i]表示到第i个位置的个数
dp[i]记录什么?这里发现a的数量需要存,为读到b或?时构成ab子序列,同理ab,abc
dp[i][0]到第i位a的数量
dp[i][1]。。。ab的数量
dp[i][2]。。。abc的数量
dp[i][0]从dp[i-1][0]转移
关键点,dp过程中遇到?字符,原串个数应当乘以3。
k乘3,k表示3x,x为前面?的数量
比如?a,读到a的时候,该位的个数+3,对该位来说,有aa,ab,ac。4个a,可以自己推
for(int i=0;i<n;i++) {
if(s[i]=='a') {
dp[i][0]=(dp[i-1][0]+k)%mod;
dp[i][1]=dp[i-1][1];
dp[i][2]=dp[i-1][2];
}
if(s[i]=='b') {
dp[i][0]=dp[i-1][0];
dp[i][1]=(dp[i-1][1]+dp[i-1][0])%mod;
dp[i][2]=dp[i-1][2];
}
if(s[i]=='c') {
dp[i][0]=dp[i-1][0];
dp[i][1]=dp[i-1][1];
dp[i][2]=(dp[i-1][2]+dp[i-1][1])%mod;
}
if(s[i]=='?') {
dp[i][0]=(dp[i-1][0]*3+k)%mod;
dp[i][1]=(dp[i-1][1]*3+dp[i-1][0])%mod;
dp[i][2]=(dp[i-1][2]*3+dp[i-1][1])%mod;
k*=3;
k%=mod;
}
}
最后dp[n][2]为最终值