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 }

  • 相关阅读:
    ajax请求默认都是异步请求,怎么变为同步请求
    TP6跨域问题
    localStorage使用总结
    win10 windows management instrumentation cpu占用高解决方法
    限制性股票-股份支付
    可转债会计分类
    其他权益工具投资的交易费用计入成本
    年数总和法
    外币货币性项目汇兑差额应当计入当期损益
    chrome怎么设置点击窗口在新窗口打开
  • 原文地址:https://www.cnblogs.com/sainsist/p/11622922.html
Copyright © 2011-2022 走看看