Codeforces1234F. Yet Another Substring Reverse(状压dp)

Topic links: Portal

Ideas:

Since only one flip substring, equivalent to two to identify substrings discontinuous, to a sub-string back over, and splicing the first substring.

Since only the subject required substring of characters will not be repeated, so that regardless of the order of characters, the operation is equivalent to inverting:

Elect two non-consecutive sub-strings, and they do not have the same character, one in which two sub-string length and the answer may be.

Title repeatedly stressed, given the string of letters only the first 20 [A, T], taking into account the $ 2 ^ 10 ^ {20} = {6}, {26} = 2 ^ 6 10 ^ {*} $ 7, apparently crazy hint: use -like pressure to do this problem.

So consider binary-like pressure set of characters.


 

A simple idea :

So set X = { 'a', 'b', ..., 't'}, with | X | represents the size of the set X.

All valid subset of pre-processing the set X (in the original string can find). The time complexity is O (n * | X |) = 2 * $ 10 ^ {6} $.

And then enumerated subset X A, X, and set in the sub-A in the complement set B C, if C is valid (can be found in the original string), then | A | + | C | is the answer of one possibility.

Doing so the total time complexity is O ($ 2 ^ {| X |} * 2 ^ {| X |} $ + n * | X |) = 1e12, obviously TLE.


 

answer:

In fact, we enumerate sub-set of the set C B, if we can know the size of the active set as a subset of the maximum value B max {| C |}, can be used | A | + max {| C | } to O (1) time to update the answer. Time complexity could be reduced to O ($ 2 ^ {| X |} $)

Next, consider how the pre-max {| C |}.

If F [mask] represents the maximum effective sub mask set S to set the size of the binary representation, then:

If S is valid: f [mask] = | S |

否则:f[mask] = max{f[mask^(1<<i)] | 0 < i < |X| && mask&(1<<i) > 0}

Processing here is $ O (| X | * 2 ^ {| X |}) = 2 * 10 ^ {7} $, is feasible.


 

Code: $ O (| X | * 2 ^ {| X |} + | X | * n) $

 1 #include <bits/stdc++.h>
 2 #define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
 3 #define N 100005
 4 #define M 100005
 5 #define INF 0x3f3f3f3f
 6 #define mk(x) (1<<x)
 7 #define sz(x) ((int)x.size())
 8 #define lson(x) (x<<1)
 9 #define rson(x) (x<<1|1)
10 #define mp(a,b) make_pair(a, b)
11 #define endl '\n'
12 #define lowbit(x) (x&-x)
13 
14 using namespace std;
15 typedef long long ll;
16 typedef double db;
17 
18 /** fast read **/
19 template <typename T>
20 inline void read(T &x) {
21     x = 0; T fg = 1; char ch = getchar();
22     while (!isdigit(ch)) {
23         if (ch == '-') fg = -1;
24         ch = getchar();
25     }
26     while (isdigit(ch)) x = x*10+ch-'0', ch = getchar();
27     x = fg * x;
28 }
29 template <typename T, typename... Args>
30 inline void read(T &x, Args &... args) { read(x), read(args...); }
31 #define MAXMASK 20
32 
33 int f[mk(MAXMASK)]; // f[mask] = mask's max number of different characters
34 int main()
35 {
36     string s;
37     cin >> s; int n = s.size();
38     for (int i = 0; i < n; i++) {
39         int mask = 0;
40         for (int j = 0; j < MAXMASK && i+j < n; j++) {
41             int b = s[i+j] - 'a';
42             if (mask & mk(b))
43                 break;
44             mask |= mk(b);
45             f[mask] = j+1;
46         }
47     }
48     for (int mask = 0; mask < mk(MAXMASK); mask++) {
49         for (int i = 0; i < MAXMASK; i++) if (mask & mk(i)){
50             f[mask] = max(f[mask], f[mask ^ mk(i)]);
51         }
52     }
53     int ans = 0;
54     for (int mask = 0; mask < mk(MAXMASK); mask++) {
55         int mask1 = (mk(MAXMASK)-1) ^ mask;
56         ans = max(ans, f[mask] + f[mask1]);
57     }
58     cout << ans << endl;
59 
60     return 0;
61 }
View Code

 

Guess you like

Origin www.cnblogs.com/Lubixiaosi-Zhaocao/p/11620068.html