CF 997A Convert to Ones

传送门
题目大意

给你一个长度为 n ( n 3 × 10 5 ) 01 串,你有两种操作:

  1. 将一个子串反转(reverse),代价为 X
  2. 将一个子串翻转(flip),代价为 Y

求将这个 01 串变成全是 1 的串的最小代价。 X Y 均为给定整数。

思路

考虑全是 0 怎么办,显然直接翻转啊!什么意思呢?就是说,连续的一段,你不会去打断它,分成多段去处理,而是直接处理了。

那我们考虑把连续的 0 1 都缩起来。由于操作是对子串进行的,因此我们忽略两头的 1 ,那么现在这个串长这样:

0101010

考虑消去第一个 0 。可以反转前两个字符:
1001010

注意,如果两个相同的字符连了起来,根据前面的理论,需要认为它们缩成了一个字符。

也可以翻转前两个字符:

1001010

发现这两种操作是一样的,都可以删去开头的 0 ,或者说都可以删去一个 0 。我们的目标是删去所有 0 ,只留下一个 1 。发现,不存在别的操作能够删去更多的 0 (翻转 1 010 _ 1 虽然会消去两个 0 ,但是又会增加一个 0 ),所以就这么做就好了。

我们选择代价小的操作一直做就好了。特别地,最后还会剩下一个 0 ,这个 0 只能用翻转操作变成 1

参考代码
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <cassert>
#include <cctype>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <list>
#include <functional>
typedef long long LL;
typedef unsigned long long ULL;
using std::cin;
using std::cout;
using std::endl;
typedef LL INT_PUT;
INT_PUT readIn()
{
    INT_PUT a = 0; bool positive = true;
    char ch = getchar();
    while (!(ch == '-' || std::isdigit(ch))) ch = getchar();
    if (ch == '-') { positive = false; ch = getchar(); }
    while (std::isdigit(ch)) { a = a * 10 - (ch - '0'); ch = getchar(); }
    return positive ? -a : a;
}
void printOut(INT_PUT x)
{
    char buffer[20]; int length = 0;
    if (x < 0) putchar('-'); else x = -x;
    do buffer[length++] = -(x % 10) + '0'; while (x /= 10);
    do putchar(buffer[--length]); while (length);
}

const int maxn = int(3e5) + 5;
int n;
int x, y;
char str[maxn];

void run()
{
    n = readIn();
    x = readIn();
    y = readIn();
    scanf("%s", str);
    n = std::unique(str, str + n) - str;
    str[n] = '\0';
    int nZero = 0;
    for (int i = 0; i < n; i++)
        nZero += str[i] == '0';
    printOut(((LL)std::min(x, y) * (nZero - 1) + y) * bool(nZero));
}

int main()
{
    run();
    return 0;
}
总结

别这么心急……仔细推一下性质。这种消 01 题往往可以从个数的变化入手。

NOI 前 CF 做不来 A 题是一种怎样的体验?

猜你喜欢

转载自blog.csdn.net/lycheng1215/article/details/80956975