1 条题解
-
0
自动搬运
来自洛谷,原作者为

Siyuan
Dream OIer.搬运于
2025-08-24 21:34:55,当前版本为作者最后更新于2019-02-08 11:19:36,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
Description
题目链接:Luogu 2187
小 Z 的有一个长度为 的笔记,他规定有 个字母对不能相邻,并且是与字母顺序无关的。现在给出这个笔记,请求出最少需要擦掉多少个字母,使得整个笔记合法。
数据范围:,
Solution
我们可以很容易地写出朴素的 转移方程:
$$f_i=\min\{f_j+i-j-1\}\quad(0\le j<i,\text{第}\ i\ \text{个字母和第}\ j\ \text{个字母可以相邻}) $$显然整个转移方程的复杂度为 ,我们考虑如何优化。首先我们把带有 的项提出,得到 ,那么这个方程的实质就是求出最小的 。我们对于每个字母 维护一个 的最小值 ,每次枚举上一个字母 ,用 来更新 即可。
时间复杂度:
Code
#include <cstdio> #include <algorithm> const int N=1e5+5; int n,f[N],g[30]; char s[N]; bool e[30][30]; char getc() { char c=getchar(); while(c<'a'||c>'z') c=getchar(); return c; } int main() { scanf("%d%s",&n,s+1); int m; for(scanf("%d",&m);m--;) { int u=getc()-'a',v=getc()-'a'; e[u][v]=e[v][u]=1; } for(int i=1;i<=n;++i) { f[i]=1<<30; for(int j=0;j<26;++j) if(!e[s[i]-'a'][j]) f[i]=std::min(f[i],g[j]+i-1); g[s[i]-'a']=std::min(g[s[i]-'a'],f[i]-i); } printf("%d\n",f[n]); return 0; }
- 1
信息
- ID
- 1170
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 5
- 标签
- (无)
- 递交数
- 0
- 已通过
- 0
- 上传者