Codeforces Round #590 (Div. 3) F

Portal

Meaning of the questions:
given only the first with a \ (20 \) string of characters, you can now select some intervals to flip, ask each interval are not the same characters, the maximum length for.

Ideas:

  • First, the question is intended to be easily converted to the selected two characters are not the same for each interval, then taking the maximum length of the sum;
  • Notes that string to meet the conditions of the interval length does not exceed \ (the n-20 * \) , then the process all the range, now is the task to find two intervals, each of its characters do not want the same, and the length and maximum;
  • Because most \ (20 \) characters, the interval converted to meet the conditions of a binary number, the task is converted to find two numbers \ (a_i, a_j \) satisfies \ (a_i \ & a_j = 0 \) and binary is \ (1 \) the number and maximum;
  • Construction \ (b \) array, and \ (b_i \) to \ (a_i \) by value after a bit negated after the problem into a subset of the problem, for every \ (State \) , we find the subset \ (a_i \) binary \ (1 \) the maximum number, followed by \ (a_i, b_i \) update the answer to.
  • Direct enumeration subset of complexity is \ (3 ^ the n-\) , might \ (T \) , so \ (dp \) optimization on the line (ie, high-dimensional prefix and , it seems, also known as \ (sos (sum \ of \ Subset) \ dp \) .

In fact, as long as they meet the conditions of the interval does not exceed \ (20 * n \) months, after the idea is more natural, and the final \ (dp \) optimization should have a stock of knowledge just come out.
A very good question.
code show as below:

#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
//#define Local
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 1666666;
 
char s[N];
int n;
int a[N], b[N];
 
void run() {
    memset(b, -1, sizeof(b));
    cin >> s + 1;
    n = strlen(s + 1);
    int lim = (1 << 20) - 1;
    for(int i = 1; i <= n; i++) {
        int x = 0, c = 0;
        for(int j = i; j <= n; j++) {
            int bit = s[j] - 'a';
            if(x >> bit & 1) break;
            x |= (1 << bit); ++c;
            a[x] = c; b[lim ^ x] = c;
        }
    }
    for(int j = 0; j < 20; j++) {
        for(int i = 0; i < lim; i++) {
            if(i >> j & 1) a[i] = max(a[i ^ (1 << j)], a[i]);
        }
    }
    int ans = 0;
    for(int i = 0; i < lim; i++) {
        if(b[i] >= 0) {
            ans = max(ans, a[i] + b[i]);
        }
    }
    cout << ans << '\n';
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
#ifdef Local
    freopen("../input.in", "r", stdin);
    freopen("../output.out", "w", stdout);
#endif
    run();
    return 0;
}

Guess you like

Origin www.cnblogs.com/heyuhhh/p/11618860.html