CF1774C Ice and Fire 【dp】

题意

给定一个由01组成的长度为n1的串,每一位作为两个数对战的环境。若环境值为0,则较小的数胜利,反之则较大的数获胜。

x个人(第i个人自身的数为i)在环境中对战,共有x1场战斗。在第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]ch[i]
  • ch[i+1]=1ch[i]=0:容易发现,i+1可以放在第i场比赛并成为胜者,然后一定会被第i+1场比赛的选手击败。若ch[i1]也是1,那么i+1又可以放在第i1场比赛,又可以产生两名选手获胜的可能性;简而言之,若1串的长度为len,那么就会增加len名胜者。

  • ch[i+1]=0ch[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 @   SxtoxA  阅读(39)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
历史上的今天:
2022-01-07 线性最小二乘法
2022-01-07 图论简单代码模板(Matlab)
2022-01-07 树的重心、点分治学习笔记
2022-01-07 0-1整数规划
2022-01-07 插值简述
12 13
点击右上角即可分享
微信分享提示