zoukankan      html  css  js  c++  java
  • [codeforces1234F]Yet Another Substring Reverse

    题目链接

    大致题意为将某个子串进行翻转后,使得不包含相同字符的字符子串长度最长。只能翻转一次或零次。

    设一个子串的状态为包含字符的二进制。如子串为$abacd$,则状态为$00000000000000001111$。

    根据分析可以得到,一个子串和另一个子串如果没有交集,则两个串可以经过一次翻转合并在一起。

    例如:$abcdefga$,串$ab$和串$fg$,可以通过翻转$cdefg$变成$abgfedca$。

    所以如果枚举一个状态,再枚举这个状态的补集的子集。就可以得到合法的状态。

    但是枚举子集的复杂度太大,所以我们先处理出每种合法状态有多少个字符,然后再从小到大枚举一遍状态。这样可以得到每种状态的合法子集的最大值。

    然后计算答案。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int maxn = 1e5 + 100;
     5 int dp[1 << 21], vis[21];
     6 string s;
     7 int main() {
     8     cin >> s;
     9     for (int i = 0; i < s.size(); i++) {
    10         int mark = 0, cnt = 0;
    11         memset(vis, 0, sizeof(vis));
    12         for (int j = i; j < s.size(); j++) {
    13             if (vis[s[j] - 'a'])
    14                 break;
    15             vis[s[j] - 'a'] = 1;
    16             mark |= (1 << (s[j] - 'a'));
    17             cnt++;
    18             dp[mark] = cnt;
    19         }
    20     }
    21     for (int i = 0; i < (1 << 20); i++)
    22         for (int j = 0; j < 20; j++)
    23             if (i & (1 << j))
    24                 dp[i] = max(dp[i], dp[i ^ (1 << j)]);
    25     int ans = 0;
    26     for (int i = 0; i < (1 << 20); i++)
    27         ans = max(ans, dp[i] + dp[i ^ ((1 << 20) - 1)]);
    28     printf("%d
    ", ans);
    29 }

  • 相关阅读:
    面试常见问题
    Servlet上传下载
    Java五大框架
    Jquery
    JavaEE
    Html学习
    JavaSE高级
    面向过程基础
    Java开发软件安装及配置
    JAVA的类加载机制和Class类
  • 原文地址:https://www.cnblogs.com/sainsist/p/11622922.html
Copyright © 2011-2022 走看看