ARC081E. Don't Be a Subsequence
$\newcommand{\next}{\mathsf{next}}$
Let $S$ be a string of lower case English letters. If there can be found all subsequences of length $L$ in $S$, then $S$ can be divided into $L$ segments, each contains all the 26 letters, which implies length of $S$ is at least $26L$.
This observation leads us to a solution. Let $\dp[i]$ be the maximum number of the aforementioned segments that the suffix of $S$ that starts at index $i$ can be divided into. The DP can be done in $O(|S|)$ time. The shortest string that is not a subsequence of $S$ has a length of $M = \dp[0] + 1$ ($S$ is 0-indexed).
Let $\next[i][j]$ be the position of the first occurrence of letter $j$ to the right of position $i$ (including position $i$). We can compute the $\next$ array in $O(26|S|)$ time.
Using the $\next$ and $\dp$ arrays, we can construct the answer as follows:
Start with an empty string $T$. Iterate the $\dp[0] + 1$ positions of the answer string from left to right. For each position $i$, iterate over the letters from 'a' to 'z'. For each letter $j$, check whether it is possible to get an answer if we append $j$ to $T$. Let $k$ be position of the last letter of the first occurrence of $Tj$ in $S$ as a subsequence, it is ok to append letter $j$ to $T$ if the suffix $S[k + 1, |S|)$ does not contain all subsequences of length $M - |T| - 1$ i.e. $\dp[k + 1] < M - |T| - 1$. This check can be done efficiently, see the following code for detail.
code
int main() {
string s;
scan(s);
int n = SZ(s);
vb vis(26);
int cnt = 0;
vi dp(n + 1);
int length = 0;
down (i, n - 1, 0) {
if (!vis[s[i] - 'a']) {
vis[s[i] - 'a'] = true;
++cnt;
if (cnt == 26) {
++length;
fill(all(vis), false);
cnt = 0;
}
}
dp[i] = length;
}
vv next(n, vi(26));
fill(all(next.back()), n);
next.back()[s.back() - 'a'] = n - 1;
down (i, n - 2, 0) {
rng(j, 0, 26) {
next[i][j] = s[i] - 'a' == j ? i : next[i + 1][j];
}
}
++length;
int pos = 0;
while (length > 0) {
rng (j, 0, 26) {
int t = next[pos][j];
if (t < n && dp[t + 1] == length - 1) continue;
if (t < n) {
pos = t + 1;
}
cout << char('a' + j);
break;
}
--length;
}
cout << '\n';
return 0;
}
ARC081E. Don't Be a Subsequence的更多相关文章
- [LeetCode] Arithmetic Slices II - Subsequence 算数切片之二 - 子序列
A sequence of numbers is called arithmetic if it consists of at least three elements and if the diff ...
- [LeetCode] Is Subsequence 是子序列
Given a string s and a string t, check if s is subsequence of t. You may assume that there is only l ...
- [LeetCode] Wiggle Subsequence 摆动子序列
A sequence of numbers is called a wiggle sequence if the differences between successive numbers stri ...
- [LeetCode] Increasing Triplet Subsequence 递增的三元子序列
Given an unsorted array return whether an increasing subsequence of length 3 exists or not in the ar ...
- [LeetCode] Longest Increasing Subsequence 最长递增子序列
Given an unsorted array of integers, find the length of longest increasing subsequence. For example, ...
- 动态规划求最长公共子序列(Longest Common Subsequence, LCS)
1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...
- 【LeetCode】Increasing Triplet Subsequence(334)
1. Description Given an unsorted array return whether an increasing subsequence of length 3 exists o ...
- CF724D. Dense Subsequence[贪心 字典序!]
D. Dense Subsequence time limit per test 2 seconds memory limit per test 256 megabytes input standar ...
- UVA 11404 Palindromic Subsequence[DP LCS 打印]
UVA - 11404 Palindromic Subsequence 题意:一个字符串,删去0个或多个字符,输出字典序最小且最长的回文字符串 不要求路径区间DP都可以做 然而要字典序最小 倒过来求L ...
随机推荐
- windows游戏编程封装窗口类
本系列文章由jadeshu编写,转载请注明出处.http://blog.csdn.net/jadeshu/article/details/22451353 作者:jadeshu 邮箱: jades ...
- elasticsearch _update api 更新部分字段内容
https://www.elastic.co/guide/cn/elasticsearch/guide/current/partial-updates.htmlupdate 请求最简单的一种形式是接收 ...
- uiautomator2 wifi连接手机
[实施方法] 手机和电脑同时连接到同一个wifi上 1.开启远程adb #开启远端adb,这一步需要手机通过USB连接到电脑 adb tcpip 5555 #结果如下:restarting in TC ...
- Intellij IDEA导入JAVA项目并启动(哈哈哈,天天都有人问)
最近有很多同学,竟然不知道如何使用Intellij IDEA打开Java项目并启动 现在来讲一下,希望不要忘记了 1.打开IDEA开机页面 Maven项目 2.Maven项目是以pom文件引入各项ja ...
- Flume-自定义 Source
Source 是负责接收数据到 Flume Agent 的组件. Source 组件可以处理各种类型.各种格式的日志数据,包括 avro.thrift.exec.jms.spooling direct ...
- Ubuntu 18.04系统下arm-linux-gcc交叉编译器安装
Ubuntu 18.04系统: arm-linux-gcc 4.4.3版本. 安装arm-linux-gcc将压缩包arm-linux-gcc.tar.gz解压到arm-linux-gcc文件夹tar ...
- Vue生命周期钩子函数加载顺序的理解
Vue实例有一个完整的生命周期,也就是从开始创建.初始化数据.编译模板.挂载Dom.渲染→更新→渲染.卸载等一系列过程,我们称这是Vue的生命周期.通俗说就是Vue实例从创建到销毁的过程,就是生命周期 ...
- 关于Java 8新引入语法特性的简要说明
Java 8在语法上的主要改进就是新增了Lambda Expression以及Method Reference.由于官方网站的介绍稍显罗嗦,而且例子也有些复杂.我这里将提供一些更为浅显.直观的例子来帮 ...
- Linux中vi编辑器的使用详解
vi编辑器是Linux系统下标准的编辑器.而且不逊色于其他任何最新的编辑器.可是会用的有多少呢.下面介绍一下vi编辑器的简单用法和部分命令.让你在Linux系统中畅行无阻. 基本上vi可以分为三种状态 ...
- 依靠MySQL(frm、MYD、MYI)数据文件恢复
该方法并不是适用于所有MySQL数据库 此次恢复是朋友那边的数据查不了了,请求我支援,出于各种心理原因,我答应试试,于是就有了这篇文章和这次经历,废话不多说.... 物理条件:宿机是Ubuntu16. ...