题目链接:传送门

思路:

由于只能翻转一次子串,就相当于找出两个不连续的子串,把在后面的一个子串翻转过来,和第一个子串拼接。

因为题目仅要求子串中的字符不重复,所以字符的先后顺序无关,翻转的操作就相当于:

选出两个不连续的子串,且他们没有相同的字符,两个子串的长度之和就是答案的一种可能。

题目中反复强调,给出的字符串只有前20个字母[a, t],考虑到$2^{20} = 10^{6}, 2^{26} = 6*10^{7}$,显然在疯狂暗示:要用状压来做这题。

所以考虑二进制状压字符集合。


一个朴素的想法

令集合X = {'a', 'b',..., 't'},用|X|表示集合X的大小。

预处理出集合X的所有有效子集(在原字符串中能找得到)。时间复杂度为O(n*|X|) = 2*$10^{6}$。

然后再枚举X的子集A,和集合A在X中的补集B的子集C,若C是有效的(在原字符串中能找到),则|A|+|C|就是答案的一种可能。

这样做的总时间复杂度是O($2^{|X|}* 2^{|X|}$ + n*|X|) = 1e12,显然会TLE。


题解:

实际上,我们在枚举集合B的子集C的时候,如果我们能知道集合B的有效子集的大小的最大值max{|C|},就可以用|A|+max{|C|}以O(1)的时间来更新答案了。时间复杂度可以下降到O($2^{|X|}$)

接下来考虑如何预处理出max{|C|}。

如果用f[mask]表示,以mask二进制表示的集合S的最大有效子集的大小,那么:

如果S是有效的:f[mask] = |S|

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

这里的处理是$O(|X|*2^{|X|}) = 2*10^{7}$,是可行的。


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

 #include <bits/stdc++.h>
#define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define N 100005
#define M 100005
#define INF 0x3f3f3f3f
#define mk(x) (1<<x)
#define sz(x) ((int)x.size())
#define lson(x) (x<<1)
#define rson(x) (x<<1|1)
#define mp(a,b) make_pair(a, b)
#define endl '\n'
#define lowbit(x) (x&-x) using namespace std;
typedef long long ll;
typedef double db; /** fast read **/
template <typename T>
inline void read(T &x) {
x = ; T fg = ; char ch = getchar();
while (!isdigit(ch)) {
if (ch == '-') fg = -;
ch = getchar();
}
while (isdigit(ch)) x = x*+ch-'', ch = getchar();
x = fg * x;
}
template <typename T, typename... Args>
inline void read(T &x, Args &... args) { read(x), read(args...); }
#define MAXMASK 20 int f[mk(MAXMASK)]; // f[mask] = mask's max number of different characters
int main()
{
string s;
cin >> s; int n = s.size();
for (int i = ; i < n; i++) {
int mask = ;
for (int j = ; j < MAXMASK && i+j < n; j++) {
int b = s[i+j] - 'a';
if (mask & mk(b))
break;
mask |= mk(b);
f[mask] = j+;
}
}
for (int mask = ; mask < mk(MAXMASK); mask++) {
for (int i = ; i < MAXMASK; i++) if (mask & mk(i)){
f[mask] = max(f[mask], f[mask ^ mk(i)]);
}
}
int ans = ;
for (int mask = ; mask < mk(MAXMASK); mask++) {
int mask1 = (mk(MAXMASK)-) ^ mask;
ans = max(ans, f[mask] + f[mask1]);
}
cout << ans << endl; return ;
}

Codeforces1234F. Yet Another Substring Reverse(状压dp)的更多相关文章

  1. fzu2188 状压dp

    G - Simple String Problem Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%I64d & ...

  2. HDU 1074 Doing Homework【状压DP】

    Doing Homework Problem Description Ignatius has just come back school from the 30th ACM/ICPC. Now he ...

  3. 【XSY2745】装饰地板 状压DP 特征多项式

    题目大意 你有\(s_1\)种\(1\times 2\)的地砖,\(s_2\)种\(2\times 1\)的地砖. 记铺满\(m\times n\)的地板的方案数为\(f(m,n)\). 给你\(m, ...

  4. Codeforces Beta Round #8 C. Looking for Order 状压dp

    题目链接: http://codeforces.com/problemset/problem/8/C C. Looking for Order time limit per test:4 second ...

  5. 状压DP的总结

    状压dp的标志 ①数据小 ②通过题目所给出的条件以后得到的特征集合小 一:CF259div2 D: 题目大意:保证b[i]中每个数互质,给出a[i],然后求1~n的abs(a[i]-b[i])最小.a ...

  6. UVa 1204 Fun Game (状压DP)

    题意:有一些小孩(至少两个)围成一圈,有 n 轮游戏,每一轮从某个小孩开始往左或者往右伟手帕,拿到手帕写上自己的性别(B,G),然后以后相同方向给下一个. 然后在某个小孩结束,给出 n 轮手帕上的序列 ...

  7. FZU - 2218 Simple String Problem(状压dp)

    Simple String Problem Recently, you have found your interest in string theory. Here is an interestin ...

  8. 状压DP之LGTB 与序列

    题目 思路 这道题竟然是状压DP,本人以为是数论,看都没看就去打下一题的暴力了,哭 \(A_i\)<=30,所以我们只需要考虑1-58个数,再往后选的话还不如选1更优,注意,1是可以重复选取的, ...

  9. 7月15日考试 题解(链表+状压DP+思维题)

    前言:蒟蒻太弱了,全打的暴力QAQ. --------------------- T1 小Z的求和 题目大意:求$\sum\limits_{i=1}^n \sum\limits_{j=i}^n kth ...

  10. Atcoder Regular Contest 093 D - Dark Horse(组合数学+状压 dp)

    Atcoder 题面传送门 & 洛谷题面传送门 常规题,简单写写罢((( 首先 \(1\) 的位置是什么不重要,我们不妨钦定 \(1\) 号选手最初就处在 \(1\) 号位置,最后答案乘个 \ ...

随机推荐

  1. JavaScript难点笔记

    前言 由于工作需求重新回顾了一下JavaScript,以下内容是我以前的学习笔记和其他参考资料整理完善后的内容,都是常用到的,使用频率比较高的,自己必须得精通的知识点的总结,便以后再复习参考. 第一章 ...

  2. .net sqlite 内存溢出 问题的分析与解决。

    一个小的工具网站,用了sqlite数据库,在并发小的情况一切正常,但是并发量上来之后,就报"out of memory"错误了. 分析了代码,就是很简单的根据一个条件取一段数据,并 ...

  3. curl下载文件时自动创建目录

    有时候需要自动创建多级目录 按照如下格式即可 curl -o d:/lei/demo/test.jpg --create-dirs http://img.7160.com/uploads/allimg ...

  4. [ros] ros入门记录

    ROS入门 半天入门ROS,总体感觉比较好理解,python写不用编译超级爽,学完ros去学电控去了. ros2比ros1好用,所以最终是学ros2. ros1 安装 添加源 > sudo sh ...

  5. 基于EasyHook实现监控explorer资源管理器文件复制、删除、剪切等操作

    一.前言 最近自己在研究一个项目,需要实现对explorer资源管理器文件操作的监控功能,网上找到一些通过C++实现Hook explorer文件操作的方法,由于本人习惯用.NET开发程序,加之C/C ...

  6. CentOS7配置静态IP中NM_CONTROLLED不要设置为NO

    这个是网络管理的,之前一直是把这个选项设置为NO,然后在CentOS其中,每次重启网络服务都会失败,后来把这个设为YES就可以了.

  7. 如何复制CSDN上他人的博客文章到自己博客下

    原作者:hello_world!(CSDN) 原文地址:https://jingyan.baidu.com/article/0964eca24e159c8285f53618.html</a> ...

  8. robot framework UI自动化之登录

    前面已写环境的搭建,接下来就可以直接进行UI自动化的编写工作了 目录 1.准备工作 2.了解定位 3.一个登录案例 1.准备工作 第一步:需要使用chrome浏览器来测试,因此首先要有一个驱动,下载好 ...

  9. JavaScript对象之--- RegExp

    1.概述 正则表达式是描述字符模式的对象. 正则表达式用于对字符串模式匹配以及检索替换: 2.语法 前者为模式,后者为修饰符. var reg = new RegExp( "xyz" ...

  10. ---Mock---基本使用

    一.mock解决的问题 开发时,后端还没完成数据输出,前端只好写静态模拟数据.数据太长了,将数据写在js文件里,完成后挨个改url.某些逻辑复杂的代码,加入或去除模拟数据时得小心翼翼.想要尽可能还原真 ...