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 ... 
随机推荐
- Java进阶知识25 Spring与Hibernate整合到一起
			1.概述 1.1.Spring与Hibernate整合关键点 1) Hibernate的SessionFactory对象交给Spring创建. 2) hibernate事务交给spring的声明 ... 
- 关于matlab GUI 的一些总结
			最近在 用matlab做一个GUI的用户界面 大多都是百度出来 摸索的学习 总结一下遇到的一些问题和解决方法 一: 在文本框动态显示文本 (保留之前的文本并显示当前文本内容): 在文本框显示文本 基本 ... 
- C语言学习笔记11- 文件I/O
			C语言学习笔记11- 文件I/O ..待编辑 文件操作(CRT.C++.WIN API.MFC) 
- html预加载之link标签
			我们之前提及过link rel 里面有preload和prefetch.modulepreload,都是用于预加载资源 <link rel="preload" href=&q ... 
- Python3使用openpyxl读写Excel文件
			Python中常用的操作Excel的三方包有xlrd,xlwt和openpyxl等,xlrd支持读取.xls和.xlsx格式的Excel文件,只支持读取,不支持写入.xlwt只支持写入.xls格式的文 ... 
- Zhejiang Provincial Collegiate Programming Contest + ZOJ Monthly
			题目链接:https://vjudge.net/contest/152802#overview. 前五题以前做过了.不过还是没能全A= =. 前三题水题,略过. 第四题是找规律,暴力打表找一下循环节即 ... 
- TypeError: Data location must be "memory" for return parameter in function, but none was given.
			在用truffle编译智能合约时,报错 TypeError: Data location must be "memory" for return parameter in fu ... 
- Qt编写安防视频监控系统8-双击节点
			一.前言 在所有的视频监控系统中,双击摄像机的节点,对应摄像机加载到当前焦点通道显示,这个都是必须具备的功能,还有一些厂家会做双击NVR节点,自动加载该NVR下的所有摄像机全部显示,从通道1开始到通道 ... 
- EasyUI入门配置
			EasyUI是一款基于jQuery的前端插件,简化了开发,免去编写复杂的js和css即可实现不错的显示效果. 基本配置: index.html <!DOCTYPE html> <ht ... 
- tmpfs使用完毕导致数据库无法正常工作
			df -h 查看 重新启动服务器就可以了 
