括号字符串期望
给一个仅由‘(’,')','?'组成的字符串,字符串长度为n,‘?’可以变换成'(',')'。变换后的相邻括号对的数学期望为E,求E*2^n(结果必为正整数,可证明),结果对10^9+7取模。仅当s[i]='('且s[i+1]=')'时,才构成一个相邻括号对。
相邻括号对定义
仅当s[i]='('且s[i+1]=')'时,才构成一个相邻括号对。
输入格式
·第一行:整数n (1 ≤ n ≤ 10^6)
·第二行:字符串s
输出格式
一个整数,表示E×2^n mod 10^9+7
字符串 (???),长度为 5
这里有 3 个 '?',所以有 2^3 = 8 种可能的替换方式。
枚举所有替换方式
-
( ( ( ( )→((())) 1 -
( ( ( ) )→((()) 1 -
( ( ) ( )→(()() 2 -
( ( ) ) )→(())) 1 -
( ) ( ( )→()(() 2 -
( ) ( ) )→()()) 2 -
( ) ) ( )→())(() 2 -
( ) ) ) )→()))) 1
计算相邻括号对总数
将所有情况的相邻括号对相加:1 + 1 + 2 + 1 + 2 + 2 + 2 + 1 = 12。
计算期望 E
期望 E 是相邻括号对的总和除以替换方式的数量:E = 12 / 8 = 1.5。
计算 E * 2^n
n = 5, 2^5 = 32。所以 E * 2^n = 1.5 * 32 = 48。
取模
48 mod (10^9 + 7) = 48(因为 48 < 10^9 + 7)。

#include <iostream> #include <string> #include <vector> using namespace std; const int MOD = 1e9 + 7; int main() { int n; string s; cin >> n >> s; vector<int> pow2(n + 1); pow2[0] = 1; for (int i = 1; i <= n; ++i) { pow2[i] = (pow2[i - 1] * 2) % MOD; } int total = 0; for (int i = 0; i < n - 1; ++i) { int m = 0; bool possible = false; if ((s[i] == '(' || s[i] == '?') && (s[i + 1] == ')' || s[i + 1] == '?')) { possible = true; m = (s[i] == '?') + (s[i + 1] == '?'); } if (possible) { total = (total + pow2[n - m]) % MOD; } } cout << total << endl; return 0; }
浙公网安备 33010602011771号