HUTXXXX DNAANDDNA 贪心

对于一个串,我们可以这样考虑,首先我们从串的最后面开始向前遍历。

对于一个串是 "XXXXAA",那么对于后面这两个A,我们是不用做任何考虑的,我们甚至可以直接认为这个串没有后面这两位。

对于一个串是 "XXXXBB",那么我们是一定要选择反转的,因为单次操作的话将这两个(或者多个)B变成A需要两次操作,而我们通过翻转整个串,再翻转前N-2个串同样可以达到这个效果。但是我们翻转整个串可能为前面的字符串改变作了贡献。

对于一个串是 "XXXXAB",那么我们是一定进行单个字符替换的。我们可以这样考虑,如果我们通过一次翻转操作来改变最后面的这一个B,那么我们是不是一定把其前面的一个A变成了B,让前面这个B再变成A我们是不是还要花上一次的操作时间,如果说翻转对前面的字符串作了贡献,那么我们还不如省下改变B变A的那一次时间来直接翻转A前面的前缀。

这里用一个0 1的变量来记录当前确定当前字符是变成了A还是变成了B,直接赋值明显太不靠谱了。

代码如下:

#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

int N;

char s[1000005], r[5] = "AB";

int main()
{
    int sp, cnt, j;
    while (scanf("%d", &N) == 1) {
        sp = cnt = 0;
        j = N;
        scanf("%s", s + 1);
        for (int i = N; i >= 1; i = j) {
            if (s[i] == r[sp]) { --j; continue; } 
            for (j = i - 1; j >= 1; --j) {
                if (s[j] != r[!sp]) { break; } 
            }
            if (i - j > 1) {  // 有两个以上连续的B
                sp ^= 1;
            }
            ++cnt;
        }
        printf("%d\n", cnt);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Lyush/p/2605802.html