Codeforces1234F. Yet Another Substring Reverse(状压dp)
题目链接:传送门
思路:
由于只能翻转一次子串,就相当于找出两个不连续的子串,把在后面的一个子串翻转过来,和第一个子串拼接。
因为题目仅要求子串中的字符不重复,所以字符的先后顺序无关,翻转的操作就相当于:
选出两个不连续的子串,且他们没有相同的字符,两个子串的长度之和就是答案的一种可能。
题目中反复强调,给出的字符串只有前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)的更多相关文章
- fzu2188 状压dp
G - Simple String Problem Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%I64d & ...
- HDU 1074 Doing Homework【状压DP】
Doing Homework Problem Description Ignatius has just come back school from the 30th ACM/ICPC. Now he ...
- 【XSY2745】装饰地板 状压DP 特征多项式
题目大意 你有\(s_1\)种\(1\times 2\)的地砖,\(s_2\)种\(2\times 1\)的地砖. 记铺满\(m\times n\)的地板的方案数为\(f(m,n)\). 给你\(m, ...
- 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 ...
- 状压DP的总结
状压dp的标志 ①数据小 ②通过题目所给出的条件以后得到的特征集合小 一:CF259div2 D: 题目大意:保证b[i]中每个数互质,给出a[i],然后求1~n的abs(a[i]-b[i])最小.a ...
- UVa 1204 Fun Game (状压DP)
题意:有一些小孩(至少两个)围成一圈,有 n 轮游戏,每一轮从某个小孩开始往左或者往右伟手帕,拿到手帕写上自己的性别(B,G),然后以后相同方向给下一个. 然后在某个小孩结束,给出 n 轮手帕上的序列 ...
- FZU - 2218 Simple String Problem(状压dp)
Simple String Problem Recently, you have found your interest in string theory. Here is an interestin ...
- 状压DP之LGTB 与序列
题目 思路 这道题竟然是状压DP,本人以为是数论,看都没看就去打下一题的暴力了,哭 \(A_i\)<=30,所以我们只需要考虑1-58个数,再往后选的话还不如选1更优,注意,1是可以重复选取的, ...
- 7月15日考试 题解(链表+状压DP+思维题)
前言:蒟蒻太弱了,全打的暴力QAQ. --------------------- T1 小Z的求和 题目大意:求$\sum\limits_{i=1}^n \sum\limits_{j=i}^n kth ...
- Atcoder Regular Contest 093 D - Dark Horse(组合数学+状压 dp)
Atcoder 题面传送门 & 洛谷题面传送门 常规题,简单写写罢((( 首先 \(1\) 的位置是什么不重要,我们不妨钦定 \(1\) 号选手最初就处在 \(1\) 号位置,最后答案乘个 \ ...
随机推荐
- EasyUI combobox下拉框添加水平滚动条和垂直滚动条
在EasyUI中combobox组件设置滚动条: 1.垂直滚动条:设置panelHeight属性,默认200,组件的数据过多滚动条自动出现,设置auto,则不出现滚动条. 2.水平滚动条:水平滚动条在 ...
- Oracle JET Router 与 Module 数据传递
Oracle JET 组件间数据传递方法. 路由:父路由:customers Router 子路由: cust Router 这里 Router 和 module 结合使用. customer 包括 ...
- 使用指定MTU到特定IP
ping指令使用指定MTU到特定IP 命令如下 45.58.185.18 这里MTU为1300
- 【洛谷P2016战略游戏】
树形dp的经典例题 题目描述 Bob喜欢玩电脑游戏,特别是战略游戏.但是他经常无法找到快速玩过游戏的办法.现在他有个问题. 他要建立一个古城堡,城堡中的路形成一棵树.他要在这棵树的结点上放置最少数目的 ...
- ES6字符串的拓展
字符串的遍历接口 for...of循环遍历. for (let codePoint of 'foo') { console.log(codePoint) } // "f" // & ...
- spring的组件工厂后置处理器——BeanFactoryPostProcessor
作用和调用时机 spring有两种后置处理器: 1. 组件后置处理器——org.springframework.beans.factory.config.BeanPostProcessor: 2. 工 ...
- 【奇技淫巧】过滤了字母和数字,如何写 shell
日期:2018-08-13 11:56:26 作者:Bay0net 介绍:金融行业正式比赛的一个题目 0x01.题目信息 文中给了一个代码 <?php include 'flag.php'; i ...
- nslookup的安装方法
1.直接使用yum安装,没有找到:yum install nslookup 2.yum provides nslookup查询nslookup在哪个套件里面 3.根据上面的提示,在"*/ns ...
- C++:函数求数根(总算写出来了。。。。)
[问题描述] 数根问题递归求解:输入n个正整数(输入格式中第一行为整数个数n,后续行为n个整数),输出各个数的数根.数根的定义:对于一个正整数n,我们将它的各个位相加得到一个新的数字,如果这个数字是一 ...
- 应用安全 - 工具 | 平台 - Weblogic - 漏洞 - 汇总
控制台路径 | 弱口令 前置条件 /console CVE-2016-0638 Date 类型远程代码执行 影响范围10.3.6, 12.1.2, 12.1.3, 12.2.1 CVE-2016 ...