题目描述
给定一个长度为 NN 的字符串 SS,Victor 的目标是将其中的 e
全部删除,而不删除其他字符。
Victor 使用 Vim
来解决这个问题。
然而,Victor 并不熟悉 Vim
,他只知道这里面的三个指令:
x
:删除光标处的字符,光标位置不变,不可以在最后的字符处使用这个命令。h
:将光标向左移动一格,如果光标位于第一个位置,则光标不动。f
:其后接一个字符 cc,其将会将光标移至其右边的第一个字符 cc,c\not =c=e
。
请计算将其中的 e
全部删除,而不删除其他字符的最小按键数。
输入格式
第一行为一个整数 NN。
接下来一行一个字符串 SS。
输出格式
仅一行一个整数,表示将其中的 e
全部删除,而不删除其他字符的最小按键数。
输入输出样例
输入 #1复制
35 chefeddiefedjeffeachbigagedegghehad
输出 #1复制
36
说明/提示
样例解释
fdhxhhxffhxfahxhhhxhhhxfdhxfghxfahhx
为最优解。
数据范围及限制
- 对于 5050 分的数据,保证 N\le 500N≤500。
- 对于另外 1010 分的数据,保证 N\le 5\times 10^3N≤5×103。
- 对于 100\%100% 的数据,保证 1\le N\le 7\times 10^41≤N≤7×104,S_i\in\{Si∈{
a
\sim∼j
\}},S_1,S_N\not=S1,SN=e
。
译者提醒:实在是搞不懂怎样设置了,所以按洛谷默认的来。
说明
本题译自 Baltic Olympiad in Informatics 2013 Day 2 T3 Vim。
上代码:
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=7e4,alpha='k'-'a'+1;
int n,len,cnte,f[maxn+1][alpha],g[maxn+1][alpha][alpha];
bool key[maxn+2];
char s[maxn+3];
int main()
{
memset(f,0x3f,sizeof f);
memset(g,0x3f,sizeof g);
scanf("%d\n",&n);
for(int i=1,check=0;i<=n;++i)
{
char t=getchar();
if(t=='e')
check=++cnte;
else
{
key[++len]=check;
s[len]=t-'a';
check=0;
}
}
f[0][s[1]]=0;
for(int i=1;i<=len;++i)
for(int j=0;j<alpha;++j)
{
if(j!=s[i])
{
if(!key[i])
f[i][j]=f[i-1][j];
f[i][j]=min(f[i][j],g[i-1][s[i]][j]);
}
f[i][j]=min(f[i][j],min(f[i-1][s[i]],g[i-1][s[i]][s[i]])+2);
for(int k=0;k<alpha;++k)
{
if(j!=s[i]&&k!=s[i])
g[i][j][k]=g[i-1][j][k]+1;
if(j!=s[i])
g[i][j][k]=min(g[i][j][k],min(f[i-1][j],g[i-1][j][s[i]])+3);
if(k!=s[i])
g[i][j][k]=min(g[i][j][k],g[i-1][s[i]][k]+3);
g[i][j][k]=min(g[i][j][k],min(g[i-1][s[i]][s[i]]+5,f[i-1][s[i]]+5));
}
}
printf("%d",f[len][alpha-1]+(cnte<<1)-2);
return 0;
}