CF1234F Yet Another Substring Reverse
你看字符集大小,显然状压,用1代表这个连续不同字符段(也就是题里定义的字符串)里面有这个字符。那么我们直接随便压一压,然后dp。
我们可以先处理出来 \(f_{i}\) 然后可以枚举它的补集,让这两个字符串拼接起来,答案就是 \(\max{f_{i}+f_{i \bigoplus ((1 <<20)-1)}}\)
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long ll;
const ll MAXN = 1e6+10, MAXM = 20;
ll N, M, f[1LL << (MAXM + 1)], ans;
char ss[MAXN];
int main() {
    scanf("%s", ss+1);
    N = strlen(ss+1);
    for (ll i = 1; i <= N; i++) {
        ll mk = 0;
        for (ll j = 0; j < MAXM && i + j <= N; j++) {
            ll now = ss[i + j] - 'a';
            if (mk & (1LL << now)) break;
            mk |= (1LL << now);
            f[mk] = j + 1;
        }
    }
    for (ll i = 0; i < (1LL << MAXM); i++)
        for (ll j = 0; j < MAXM; j++)
            if (i & (1LL << j))
                f[i] = max(f[i], f[i ^ (1LL << j)]);
    for (ll i = 0; i < (1LL << MAXM); i++) 
        ans = max(f[i] + f[i ^ ((1LL << MAXM)-1)], ans);
    printf("%lld\n", ans);
    return 0;
}
    希望我们都有一个光明的未来
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号