Educational Codeforces Round 110 C(最长连续字串,dp),D(左右子树继承贡献dp)
C. Unstable String
题目大意:
给定一个长度为n的字符串且只包括'0','1','?',其中如果一个字串是由01交替组成的则称谓不稳定的,如果碰到'?'则可以将其转化为0/1,求不稳定的字串的个数。(单独的0/1/?也为不稳定字串)。
解题思路:
不稳定字串的个数可以转化为到第i位,不稳定字串的最大长度
例如01010,对于第1位,贡献为1,第2位贡献为2(1,01),第三位贡献为3(0,10,010),以此类推
所以定义f[i][j]为,第i位为0/1时的最长不稳定串的长度,每次ans += max(f[i][0],f[i][1])
代码实现:
#include<bits/stdc++.h>
using namespace std;
# define int long long
# define endl "\n"
const int N = 2e5 + 10, inf = 1e18;
void solve() {
string s;
cin >> s;
int n = s.size();
vector<vector<int>> f(n, vector<int>(2, 0));
int ans = 0;
for (int i = 0; i < n; ++i) {
if (i == 0) {
if (s[i] == '0') f[i][0] = 1;
else if (s[i] == '1') f[i][1] = 1;
else f[i][0] = f[i][1] = 1;
} else {
if (s[i] == '0') f[i][0] = f[i - 1][1] + 1;
else if (s[i] == '1') f[i][1] = f[i - 1][0] + 1;
else {
f[i][1] = f[i - 1][0] + 1;
f[i][0] = f[i - 1][1] + 1;
}
}
ans += max(f[i][0],f[i][1]);
}
cout<<ans<<endl;
}
int tt;
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
tt = 1;
cin >> tt;
while (tt--) solve();
return 0;
}
D. Playoff Tournament
题目大意:
给定一个数n,总共有1<<n个人参加比赛,其中1与2对抗,3与4对抗...,每轮胜出的人都会和相邻比赛胜出的人继续比赛,直到最后胜出一人。
现在给定一个长度为(1<<n-1)的字符串只包含0/1/?用来表示第i场比赛的获胜规则
,0表示id较低者获胜,1表示id较高者获胜,?表示都有可能胜。
给定m次修改,求每次修改后可能胜出的人数。
解题思路:
对于每场比赛如果规定了比赛规则那么毫无疑问,每场的能够决定的胜者个数则为1,下一轮比赛则如果为0,胜者个数则会继承于左子树,否则继承于右子树,如果是?则继承左右子树之和。其实这样一分析dp的过程就就浮现出来了,定义f[i]表示第i场可能胜出的人数,如果第i场为0,则继承f[i*2],否则继承f[i*2+1],如果为?则继承f[i*2]+f[ i*2+1] (数组模拟二叉树)
代码实现:
#include<bits/stdc++.h>
using namespace std;
# define int long long
# define endl "\n"
const int N = 2e5 + 10, inf = 1e18;
void solve() {
int n;
cin >> n;
string s;
cin >> s;
int len = 1 << n;
vector<int> f(2 * len);
for (int i = len; i <= len * 2 - 1; ++i) {
f[i] = 1;
}
int now = 0;
for (int i = len - 1; i >= 1; --i) {
f[i] = (s[len - 1 - i] == '0' ? f[2 * i+1] : (s[len - 1 - i] == '1' ? f[2 * i] : f[2 * i] + f[2 * i + 1]));
}
int q;
cin >> q;
while (q--) {
int p;
char c;
cin >> p >> c;
--p;
s[p] = c;
for (int i = len - 1 - p; i != 0; i /= 2) {
f[i] = (s[len - 1 - i] == '0' ? f[2 * i+1] : (s[len - 1 - i] == '1' ? f[2 * i] : f[2 * i] + f[2 * i + 1]));
}
cout<<f[1]<<endl;
}
}
int tt;
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
tt = 1;
// cin >> tt;
while (tt--) solve();
return 0;
}

浙公网安备 33010602011771号