CF1774C Ice and Fire 【dp】
题意
给定一个由\(0\)和\(1\)组成的长度为\(n-1\)的串,每一位作为两个数对战的环境。若环境值为\(0\),则较小的数胜利,反之则较大的数获胜。
\(x\)个人(第\(i\)个人自身的数为\(i\))在环境中对战,共有\(x-1\)场战斗。在第\(i\)个环境中任选两个剩下的人进行对战,胜者在第\(i+1\)个环境与下一个人对战。
求参加人数不超过\(x\)的人的条件下,每种人数下会有多少人有可能获胜。
分析
令\(dp[i]\)表示\(x=i\)时的获胜人数。
假设当前环境为\(ch[i]\),尝试分类讨论:
- \(ch[i+1]=ch[i]\):
-
\(ch[i+1]=ch[i]=0\):无论在任何排列的情况下,值为\(i+1\)的数都不能成为胜者,对答案无贡献,因为\(i+1\)比前\(i\)个数都要大。
-
\(ch[i+1]=ch[i]=1\):胜者\(i\)会被\(i+1\)替代,答案无变化
-
故\(dp[i+1]=dp[i]\)
- \(ch[i+1] \neq ch[i]\):
-
\(ch[i+1]=1,ch[i]=0\):容易发现,\(i+1\)可以放在第\(i\)场比赛并成为胜者,然后一定会被第\(i+1\)场比赛的选手击败。若\(ch[i-1]\)也是1,那么\(i+1\)又可以放在第\(i-1\)场比赛,又可以产生两名选手获胜的可能性;简而言之,若\(1\)串的长度为\(len\),那么就会增加\(len\)名胜者。
-
\(ch[i+1]=0,ch[i]=1\):同上。
-
故\(dp[i+1]=dp[i]+len\),其中\(len\)为第\(i\)位前连续子串的长度。
Code
#include<iostream>
#include<cstring>
const int maxn = 2e5 + 10;
int T, n, dp[maxn];
char ch[maxn];
int main() {
scanf("%d", &T);
while (T--) {
scanf("%d", &n);
std::cin >> ch;
int len = 1;
dp[0] = 1;
for (int i = 1; i < n - 1; i++) {
if (ch[i] == ch[i - 1]) {
++len;
dp[i] = dp[i - 1];
} else {
dp[i] = dp[i - 1] + len;
len = 1;
}
}
for (int i = 0; i < n - 1; i++)
printf("%d ", dp[i]);
printf("\n");
}
return 0;
}

浙公网安备 33010602011771号