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]\),尝试分类讨论:

  1. \(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]\)

  1. \(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;
}
posted @ 2023-01-07 19:02  SxtoxA  阅读(56)  评论(0)    收藏  举报
12 13