[JZOJ3320] 【BOI2013】文本编辑器
题目
题目大意
给你一个文本,要删去其中所有的‘e’。
有三种操作:
h光标左移。x删除光标上面的字母(光标是横着的)。fc跳到后面的第一个字符为‘c’的位置。
问操作序列的最短长度。
思考历程
首先看错了题意,然后感觉似乎很水……后来发现错了……
接下来开始想其它的方法。
有个还不错的思路:设\(f_{i,j}\)表示前面\(i\)个‘e’被选了,现在光标在\(j\)的最小答案。
比赛的时候头昏眼花写出了一个\(O(n^4)\)的转移方程,后来在最后5分钟的时候发现其中的一对变量是重复的……也就是说,实际上是\(O(n^3)\)……
我就这么错过了50分……
(后来才知道,同样是这个状态,可以优化到\(O(10n^2)\),具体不再赘述)
正解
先推荐一篇博客:https://www.cnblogs.com/Itst/p/10339605.html
这篇博客非常详细。所以我觉得我不用说这么多了。
这题的正解是个看起来高大上的线头DP。
什么是高大上?就是名字都没听过的东西。
先说一开始的操作:将所有的‘e’删掉,答案预先加上\(2\)倍的‘e’的个数。具体原因显然。
那么必经位置就是原先前面是‘e’的位置。
题目转化为:从头开始,每次可以进行两种操作,问经过所有必经位置的最小答案。
我们形象地将文本看作一个数轴,每次的操作看作走一条边,往后跳的称作飞边,往前跳的称作走边
开始设DP状态:
\(f_{i,j}\)表示\(i\)和\(i+1\)之间的垂线与走过的边有一个交点,显然这是和飞边的交点。\(j\)为飞边落下位置上的字母;
\(g_{i,j,k}\)表示垂线与走过的边有三个交点,显然这是和两个飞边和一个走边的交点。\(j\)为前面一条飞边落下位置上的字母,\(k\)为后面一条飞边落下位置的字母。
可能有点不清楚,那我就借一下刚刚那片博客的图:
先考虑\(f_{i,j}\)的转移,有以下四种情况:
- \(f_{i-1,j}\),\(s_i\neq j\)且\(i\)不是必经点。
- \(f_{i-1,s_i}+2\)
- \(g_{i-1,s_i,j}\),\(s_i\neq j\)
- \(g_{i-1,s_i,s_i}+2\)
画画图就能理解了……再次借用图片。
再考虑\(g_{i,j}\)的转移,有以下六种情况(方程和别人的有很大区别,不要混淆了)。
(\(nex_{i,j}\)表示\(i\)后第一个\(j\)的位置)
- \(f_{i-1,j}+nex_{i,j}-i+2\),\(j\neq s_i\)
- \(f_{i-1,s_i}+nex_{i,j}-i+4\)
- \(g_{i-1,j,k}\),\(j\neq s_i\)且\(k \neq s_i\)
- \(g_{i-1,s_i,k}+nex_{i,j}-i+2\),\(k\neq s_i\)
- \(g_{i-1,j,s_i}+2\),\(j\neq s_i\)
- \(g_{i-1,s_i,s_i}+nex_{i,j}-i+4\)
这些图片当然也是我Copy过来的,不过要注意的是,我的转移中\(i+1\)和\(j\)是已经连在一起的。
原版的方程看别人博客去……(其实我之前一直不理解为什么他们不把\(i+1\)和\(j\)连在一起,后来我终于明白,它们的状态计算的答案是\(i\)之前的,后面的还没有算。在后面的转移过程中会慢慢累加,补整齐。不过我觉得我这样打好理解一点)
方程完了,剩下一点细节:初始化\(f_{0,s_1}=0\),其它为无限大;答案加上\(f_{n,'k'}\),'k'为原串中没有出现过的字符。这相当于最后连一条出去(所以还要再减\(2\))。
代码
using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 70010
inline void update(int &a,int b){a>b?a=b:0;}
int _n,n;
char _s[N],s[N];
int nex[N][11];
bool must[N];
int f[N][11],g[N][11][11];
int ans;
int main(){
scanf("%d%s",&_n,_s+1);
ans=0;
for (int i=1;i<=_n;++i)
if (_s[i]=='e')
ans+=2;
else{
s[++n]=_s[i];
if (_s[i-1]=='e')
must[n]=1;
}
memset(nex[n+1],1,sizeof nex[n+1]);
s[n+1]='k';
for (int i=1;i<=n+1;++i)
s[i]-='a';
for (int i=n;i>=1;--i){
memcpy(nex[i],nex[i+1],sizeof nex[i]);
nex[i][s[i+1]]=i+1;
}
memset(f,127,sizeof f);
memset(g,127,sizeof g);
f[0][s[1]]=0;
for (int i=1;i<=n;++i){
for (int j=0;j<=10;++j){
if (j!=s[i]){
if (!must[i])
update(f[i][j],f[i-1][j]);
update(f[i][j],g[i-1][s[i]][j]);
}
update(f[i][j],f[i-1][s[i]]+2);
update(f[i][j],g[i-1][s[i]][s[i]]+2);
}
for (int j=0;j<=10;++j)
for (int k=0;k<=10;++k){
if (j!=s[i]){
update(g[i][j][k],f[i-1][j]+nex[i][j]-i+2);
if (k!=s[i])
update(g[i][j][k],g[i-1][j][k]);
update(g[i][j][k],g[i-1][j][s[i]]+2);
}
update(g[i][j][k],f[i-1][s[i]]+nex[i][j]-i+4);
if (k!=s[i])
update(g[i][j][k],g[i-1][s[i]][k]+nex[i][j]-i+2);
update(g[i][j][k],g[i-1][s[i]][s[i]]+nex[i][j]-i+4);
}
}
ans+=f[n][10]-2;
printf("%d\n",ans);
return 0;
}
总结
见到毒瘤题的时候要仔细找找题目的性质……
DP时要善于分类讨论……不要被高大上的名字吓到了……
[JZOJ3320] 【BOI2013】文本编辑器的更多相关文章
- 富文本编辑器Simditor的简易使用
最近打算自己做一个博客系统,并不打算使用帝国cms或者wordpress之类的做后台管理!自己处于学习阶段也就想把从前台到后台一起谢了.好了,废话不多说了,先来看看富文本编辑器SimDitor,这里是 ...
- 个人网站对xss跨站脚本攻击(重点是富文本编辑器情况)和sql注入攻击的防范
昨天本博客受到了xss跨站脚本注入攻击,3分钟攻陷--其实攻击者进攻的手法很简单,没啥技术含量.只能感叹自己之前竟然完全没防范. 这是数据库里留下的一些记录.最后那人弄了一个无限循环弹出框的脚本,估计 ...
- 关于SMARTFORMS文本编辑器出错
最近在做ISH的一个打印功能,SMARTFORM的需求本身很简单,但做起来则一波三折. 使用环境是这样的:Windows 7 64bit + SAP GUI 740 Patch 5 + MS Offi ...
- 基于trie树的具有联想功能的文本编辑器
之前的软件设计与开发实践课程中,自己构思的大作业题目.做的具有核心功能,但是还欠缺边边角角的小功能和持久化数据结构,先放出来,有机会一点点改.github:https://github.com/chu ...
- UEditor百度富文本编辑器--让编辑器自适应宽度的解决方案
UEditor百度富文本编辑器的initialFrameWidth属性,默认值是1000. 不能够自适应屏幕宽度.如图1: 刚开始的时候,我是直接设置initialFrameWidth=null的.效 ...
- [bzoj1269][AHOI2006文本编辑器editor] (splay模版题 or pb_ds [rope]大法)
Description 这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器.你能帮助他吗?为了明确任务目标,可可对“文本编辑器”做了一个抽象的定义: 文本:由0个或 ...
- Bzoj1269 [AHOI2006]文本编辑器editor
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3678 Solved: 1380 Description 这些日子,可可不和卡卡一起玩了,原来可可正 ...
- PHP Ueditor 富文本编辑器
2016年12月11日 08:46:59 星期日 百度的简版富文本编辑器umeditor很久没更新了 全功能版本的配置项跟umeditor还是有区别的, 这里说下ueditor怎么对接到项目中去, 主 ...
- js中的文本编辑器控件KindEditor---那些打酱油的日子
使用文本编辑器控件KindEditor渲染文本域页面显示 this.sync()同步KindEditor的值到textarea文本框 editor.isEmpty()判断文本域是否是空 editer. ...
- Unix及类Unix系统文本编辑器的介绍
概述 Vim是一个类似于Vi的著名的功能强大.高度可定制的文本编辑器,在Vi的基础上改进和增加了很多特性.VIM是纯粹的自由软件. Vim普遍被推崇为类Vi编辑器中最好的一个,事实上真正的劲敌来自Em ...
随机推荐
- zabbix--添加host
在client配置好zabbix_agent后,如果server端没配置自动发现,那就需要创建添加host. 首先找到地方.Configuration--Hosts--Create Host 创建ho ...
- webpack 配置之入门一
webpack 是一个现代 Javascript 应用程序的模块打包器(module bundler ),它里面的功能比较多,核心模块可分为模块打包.代码分割与按需加载.这里只简单讲解下 webpac ...
- 函数隐藏参数 — this
解析器在调用函数每次都会向函数内部传递一个隐含的参数,这个隐含的参数就是this this指向的是一个对象,这个对象我们成为函数执行的上下文对象 根据函数的调用方式不用,this会指向不同的对象: 1 ...
- [Err] 1701 - Cannot truncate a table referenced in a foreign key constraint
1.SET FOREIGN_KEY_CHECKS=0; 2.DELETE FROM ACT_RE_DEPLOYMENT where 1=1; 或者 truncate table ACT_RE_DEPL ...
- Center OS 7 Apache安装配置
感谢:https://blog.csdn.net/u014157384/article/details/79497761 该作者的帮助. 自己购买了国外的服务器,想把我的网页放到服务器,网页是以web ...
- php导出csv并保存在服务器,返回csv的文件路径
<?php namespace app\common\controller; use think\Controller; use think\Db; class Csv extends Cont ...
- python中模块和包的概念
1.模块 一个.py文件就是一个模块.这个文件的名字是:模块名.py.由此可见在python中,文件名和模块名的差别只是有没有后缀.有后缀是文件名,没有后缀是模块名. 每个文件(每个模块)都是一个独立 ...
- leetcood学习笔记-203-移除链表元素
题目描述: 方法:#在改pre链表时 head中的值也改变 class Solution(object): def removeElements(self, head, val): "&qu ...
- QT install
{ https://www.bilibili.com/video/av18148008?from=search&seid=15361598961528715331 }
- 51nod 1627 瞬间移动(组合数学)
传送门 解题思路 因为每次横纵坐标至少\(+1\),所以可以枚举走的步数,枚举走的步数\(i\)后剩下的就是把\(n-1\)与\(m-1\)划分成\(i\)个有序正整数相加,所以用隔板法,\(ans= ...