Face Produces Unhappiness(贪心)

题意

给定长度为\(N\)的串\(S\),如果\(S_i\)等于L,说明第\(i\)个人面朝左边,反之则朝向右边。

\(S_i\)\(S_{i+1}\)方向相同,则高兴值加\(1\)

现在有一种操作操作:选择一个\(L\)\(R\),将\([L, R]\)序列逆序,并且将L变成RR变成L。如:对LLLRLL操作,得到RRLRRR

最多可以进行\(K\)次操作。问操作结束之后的最大高兴值是多少。

题目链接:https://atcoder.jp/contests/abc140/tasks/abc140_d

数据范围

\(1 \leq N, K \leq 10^5\)

思路

训练时猜了一个贪心思路:不妨设第一个字符为L,将\(K\)段(如果不满\(K\)段,则为全部)连续的R进行操作,操作后的序列高兴值即为答案。

这个贪心思路是正确的,下面对其进行简单解释。每次操作可以增加高兴值\(2\)或者\(1\)。当形如LRRRL时,对中间的RRR进行操作,可以增加高兴值\(2\);当LRRR时,对RRR操作可以增加高兴值\(1\)。我们优先选取第一种情况,因此顺着序列对连续的R进行操作即可。

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 100010;

int n, k;
char s[N];

int main()
{
    scanf("%d%d%s", &n, &k, s + 1);
    int ans = 0;
    char st = s[1];
    for(int i = 2; i <= n; i ++) {
        if(s[i] != st && k) {
            int j = i;
            while(j <= n && s[j] != st) s[j] = st, j ++;
            k --;
            i = j - 1;
        }
    }
    for(int i = 2; i <= n; i ++) {
        if(s[i] == s[i - 1]) ans ++;
    }
    printf("%d\n", ans);
    return 0;
}
posted @ 2022-06-23 18:02  pbc的成长之路  阅读(28)  评论(0编辑  收藏  举报