HUT-XXXX DNA-AND-DNA 贪心
对于一个串,我们可以这样考虑,首先我们从串的最后面开始向前遍历。
对于一个串是 "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; }