[线头DP]LOJ 2687 vim

Description

 

Input

第一行包含了整数N,表示该文档的长度。下一行包含N个字符,每一个都是十个小写字母“a”到“j”之一。输入的第一个和最后一个字母都不是“e”。

Output

输出一个整数,表示Victor需要删除所有的“e”最少的按键次数。
 

Sample Input

35
chefeddiefedjeffeachbigagedegghehad

Sample Output

36
解释:其中一个最优方案是:fdhxhhxffhxfahxhhhxhhhxfdhxfghxfahhx
 

Data Constraint

50%数据:N ≤ 500

另外10%的数据:N ≤ 5000

100%的数据:N ≤ 70 000

分析

线头瞎搞

 

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N=7e4+10;
const int Alpha=11;
const int Inf=0x7f7f7f7f;
int len,fakelen,cnt,le[N],f[N][Alpha],g[N][Alpha][Alpha],s[N];
char c[N];

int main() {
    scanf("%d",&len);
    scanf("%s",c+1);
    for (int i=1;i<=len;i++) {
        if (c[i]!='e') le[++fakelen]=c[i-1]=='e',s[fakelen]=c[i]-'a';
        cnt+=(c[i]=='e');
    }
    memset(f,0x7f,sizeof f);memset(g,0x7f,sizeof g);
    f[0][s[1]]=0;
    for (int i=1;i<=fakelen;i++)
        for (int j=0;j<Alpha;j++) {
            f[i][j]=min(j!=s[i]&&!le[i]?f[i-1][j]:Inf,
            min(f[i-1][s[i]]+2,min(j!=s[i]?g[i-1][s[i]][j]:Inf,g[i-1][s[i]][s[i]]+2)));
            for (int k=0;k<Alpha;k++)
            g[i][j][k]=min(j!=s[i]?f[i-1][j]+3:Inf,min(f[i-1][s[i]]+5,min(j!=s[i]&&k!=s[i]?g[i-1][j][k]+1:Inf,
            min(j!=s[i]?g[i-1][j][s[i]]+3:Inf,min(k!=s[i]?g[i-1][s[i]][k]+3:Inf,g[i-1][s[i]][s[i]]+5)))));
        }
    printf("%d",f[fakelen][Alpha-1]-2+2*cnt);
}
View Code

 

posted @ 2019-07-09 07:38  Vagari  阅读(235)  评论(0编辑  收藏  举报