AtCoder Beginner Contest 104 D题题解
D - We Love ABC
题目
Problem Statement
The ABC number of a string T is the number of triples of integers (i,j,k) that satisfy all of the following conditions:
- 1≤i<j<k≤|T| (|T| is the length of T.)
- T**i=
A
(T**i is the i-th character of T from the beginning.) - T**j=
B
- T**k=
C
For example, when T= ABCBC
, there are three triples of integers (i,j,k) that satisfy the conditions: (1,2,3),(1,2,5),(1,4,5). Thus, the ABC number of T is 3.
You are given a string S. Each character of S is A
, B
, C
or ?
.
Let Q be the number of occurrences of ?
in S. We can make 3Q strings by replacing each occurrence of ?
in S with A
, B
or C
. Find the sum of the ABC numbers of all these strings.
This sum can be extremely large, so print the sum modulo 109+7.
Constraints
- 3≤|S|≤105
- Each character of S is
A
,B
,C
or?
.
Input
Input is given from Standard Input in the following format:
S
Output
Print the sum of the ABC numbers of all the 3Q strings, modulo 109+7.
Sample Input 1
A??C
Sample Output 1
8
In this case, Q=2, and we can make 3Q=9 strings by by replacing each occurrence of ?
with A
, B
or C
. The ABC number of each of these strings is as follows:
AAAC
: 0AABC
: 2AACC
: 0ABAC
: 1ABBC
: 2ABCC
: 2ACAC
: 0ACBC
: 1ACCC
: 0
The sum of these is 0+2+0+1+2+2+0+1+0=8, so we print 8 modulo 109+7, that is, 8.
题意
给出一个序列,由'A','B','C'或 '?'组成。
思路
dp的思路,从长度末尾开始,如果j=3时,当前位为?表示可能有三种选择。否则只有一种选择。在j<3时,如果当前位置为ABC的正确位置或者为'?'时,ij应当加上i+1 j+1的情况。
代码
#pragma comment(linker, ¡°/STACK:1024000000,1024000000¡±)
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 0x3f3f3f3f;
#define REP(i,n) for(int i=0;i<(n);i++)
int main(){
string S;
cin >> S;
int N = S.size(), MOD = 1000000007;
long long dp[100010][4] = {};
for(int i = N; i >= 0; --i){
for(int j = 3; j >= 0; --j){
if(i == N){
dp[i][j] = (j == 3 ? 1 : 0);
}else{
dp[i][j] = dp[i+1][j] * (S[i] == '?' ? 3LL : 1LL);
if(j < 3 && (S[i] == '?' || S[i] == "ABC"[j])){
dp[i][j] += dp[i+1][j+1];
}
dp[i][j] %= MOD;
}
}
}
cout << dp[0][0] << endl;
}