不能相邻的字符对
来源:互联网 发布:阿里云os5.1系统root 编辑:程序博客网 时间:2024/04/30 18:10
小 W W 理 笔记
【问题 描 述】
小 W 由于购物浪费了太多时间,导致他外语课都没有好好听。为什么是外语课?不是英
语课?因为小 W 肯定会好好听英语课。由于没有好好听课, 小 W 的笔记全都记的杂乱无章,
出现了好多错误的地方。 小 W 的笔记是如此的糟糕,以至于他只记了一句例句,而且自己
还不知道是什么意思……然后在老师讲语法的时候, 小 W 又零星的记了几个字母对,老师
说:这几个字母对是绝对不能相邻的,而且相邻是不关心字母的顺序的,比如老师说,‘ab’
不能相邻,那么相同的,‘ba’也不能相邻。
现在小 W 到家了,打开了上课的笔记,然后他发现笔记有很多自相矛盾的地方:为什
么下面的不能相邻的字母对会出现在上面的例句里面呢?纠结再三, 小 W 觉得下面的东西
相对比较简单,所以记错的概率比较小……他决定在上面的例句里面擦掉几个字母,使得句
子变得合法。
但是小 W 还要把礼物送给小 M,来不及整理笔记了,就把这个艰巨的任务留给了大家,
请问大家, 小 W 最少要擦掉几个字母,才能使得上面的例句合法?
【输入格式】
第一行:一个整数 N。
第二行:一个长度为 N 的字符串,只包含小写字母,代表小 W 记下的例句。
第三行:一个整数 M,代表不能相邻的字母对的个数。
接下来 M 行:每行两个小写字母,代表不能相邻的字母对,因为小 W 太不认真了,所以可
能有重复。
【输出格式】
一行一个整数:最少要擦除的字母数。
【输入输出样例】
note.in note.out
4 1
jsoi
2
oi
mo
【 数据规模 】
对于 10%的数据,M=0
对于另外 30%的数据,N≤1000
【问题 描 述】
小 W 由于购物浪费了太多时间,导致他外语课都没有好好听。为什么是外语课?不是英
语课?因为小 W 肯定会好好听英语课。由于没有好好听课, 小 W 的笔记全都记的杂乱无章,
出现了好多错误的地方。 小 W 的笔记是如此的糟糕,以至于他只记了一句例句,而且自己
还不知道是什么意思……然后在老师讲语法的时候, 小 W 又零星的记了几个字母对,老师
说:这几个字母对是绝对不能相邻的,而且相邻是不关心字母的顺序的,比如老师说,‘ab’
不能相邻,那么相同的,‘ba’也不能相邻。
现在小 W 到家了,打开了上课的笔记,然后他发现笔记有很多自相矛盾的地方:为什
么下面的不能相邻的字母对会出现在上面的例句里面呢?纠结再三, 小 W 觉得下面的东西
相对比较简单,所以记错的概率比较小……他决定在上面的例句里面擦掉几个字母,使得句
子变得合法。
但是小 W 还要把礼物送给小 M,来不及整理笔记了,就把这个艰巨的任务留给了大家,
请问大家, 小 W 最少要擦掉几个字母,才能使得上面的例句合法?
【输入格式】
第一行:一个整数 N。
第二行:一个长度为 N 的字符串,只包含小写字母,代表小 W 记下的例句。
第三行:一个整数 M,代表不能相邻的字母对的个数。
接下来 M 行:每行两个小写字母,代表不能相邻的字母对,因为小 W 太不认真了,所以可
能有重复。
【输出格式】
一行一个整数:最少要擦除的字母数。
【输入输出样例】
note.in note.out
4 1
jsoi
2
oi
mo
【 数据规模 】
对于 10%的数据,M=0
对于另外 30%的数据,N≤1000
对于 100%的数据,N≤100000,M≤400
分析:
可以看出题目的无后效性,所以采用dp的做法。
我们定义状态f[i]表示前i个字符所需擦去的最小个数,所以有f[i]=min(f[j]+(i-j)),且j是可以与i相邻的字符。
效率O(n^2),显然不够。
我们再来看一看转移方程,由于可以与i相邻的j总共只可能是26种字符,所以我们可以维护M(j)表示最后一位保留j字符的最小擦去数,但是我们还要维护对应的j的位置,否则怎么计算(i-j)呢?仍然有两个因素限制结果,如果采取枚举一个计算另一个的做法,效率就没有降低。
如果我们不计算最小擦去数,而反过来计算最大保留数呢?
那么f[i]=max(f[j]+1),维护一个M(j),显然就可以解决问题,将复杂度降为O(n)
参考程序:
#include<cstdio>#include<algorithm>using namespace std;const int maxn=110000;int f[maxn],g[maxn];int last[30],forbid[30][30];char b[maxn];int n,m;int main(){freopen("note.in","r",stdin);freopen("note.out","w",stdout);scanf("%d",&n);scanf("%s",b+1);for (int i=1;i<=n;i++)f[i]=b[i]-'a';scanf("%d",&m);while (m--){scanf("%s",b);forbid[b[0]-'a'][b[1]-'a']=forbid[b[1]-'a'][b[0]-'a']=1;}int ans=0;for (int i=1;i<=n;i++){g[i]=1;for (int j=0;j<26;j++)if (!forbid[j][f[i]])g[i]=max(g[i],last[j]+1);last[f[i]]=max(last[f[i]],g[i]);ans=max(ans,g[i]);}printf("%d",n-ans);return 0;}
0 0
- 不能相邻的字符对
- 字符串剔除不相邻的重复字符
- 删除与某个字符相邻且相同的字符
- 计算字符中相邻位置相同字符的个数
- Python不能对字符解码的问题解析
- 随机分配座位,共50个学生,使学号相邻的同学座位不能相邻
- 随机分配座位,共50个学生,使学号相邻的同学座位不能相邻
- 从字符串中删除相同的相邻字符
- 匹配一个2个相邻并且相同的字符
- 80x86汇编语言编程:相邻两字符的判断
- 删除字符串中相邻三个或以上重复的字符
- 删除字符串中相邻三个或以上重复的字符
- 【CCF】相邻数对
- 相邻数对
- 相邻数对问题
- 相邻数对
- CCF 相邻数对
- (JAVA) 相邻数对
- 十大经典排序算法(一)
- Codeforces Round #379 (Div. 2) C. Anton and Making Potions
- test
- LeNet模型简介
- Java NIO中Selector类源码
- 不能相邻的字符对
- 64. Minimum Path Sum
- 39. Combination Sum
- 216. Combination Sum III
- Linux下的一些问题收集及解决方法(一)
- 初探swift语言的学习笔记二(可选类型?和隐式可选类型!)
- C# Regex类详解
- Spark安装
- Python语言学习讲解五:列表(List)操作方法详解