• jzoj3320. 文本编辑器&LOJ2687. 「BalticOI 2013」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

    题解

    50%
    考虑DP。
    我们设状态(f_{[i,j]})表示当前第i个位置,把前j个e都给删去的最小步数。
    怎么转移?
    由于每个f操作都是往右跳,h是往左跳。
    那么我们发现,每次从i往右跳到j后,一定是把i到j里面的所有e都删去后才继续往右跳,否则不优。
    那么每次都是把某一段的e都给删掉。
    于是就很好转移的,每次考虑枚举下一个e是什么,利用预处理求出代价后转移。
    注意各种小细节。
    时间复杂度:(O(n^3))
    60%
    我不费。(其实是我没打过)
    似乎转移状态和上面的很相似,设(f_{[i,j]})表示当前第i个位置,1~j位置的所有e都去掉的最小步数。
    我们发现,每次j是只可能往右走,而i往左跳或往右跳都是可以的。
    那么我们固定一个k,分两种情况:
    1、f操作。枚举一个新的字符,然后i往右跳。
    2、h操作。我们如果k右边i左边有e没删,那么就把i往左边跳即可。
    实际上转移好像比较猎奇。
    但是时间是(O(n^2*10))的。
    100%
    这据说是一个叫线头DP的玩意儿,我从来没有听说过。
    似乎DP比较神奇,理解起来也很容易。
    (主要是题解很棒)
    https://www.cnblogs.com/Itst/p/10339605.html、
    https://www.cnblogs.com/cjyyb/p/11146822.html
    看完你就懂了。比我写得详细多了。
    其中有一个东东没有讲得特别清楚:
    就是DP方程其实记录的是当前第i个位置以前的h操作和f操作。
    所以说在看到q的转移的时候我们可以看到它没有求i+1到j这部分的答案。
    这个地方注意,其他都很容易。

    标程

    uses math;
    var
            i,j,k,l,n,m,len,maxx,si:longint;
            mip:array[1..70000] of boolean;
            p:array[0..70000,1..11] of longint;
            q:array[0..70000,1..11,1..11] of longint;
            s,t:ansistring;
    begin
            //assign(input,'2data.in');reset(input);
            readln(n);
            readln(s);
            for i:=1 to n do
            begin
                    if s[i]='e' then
                    begin
                            inc(m);
                    end
                    else
                    begin
                            inc(len);
                            t:=t+s[i];
                            if (i>1) and (s[i-1]='e') then
                            begin
                                    mip[len]:=true;
                            end;
                    end;
            end;
            inc(len);
            t:=t+'k';
            fillchar(p,sizeof(p),127 div 3);
            fillchar(q,sizeof(q),127 div 3);
            maxx:=p[0,1];
            p[0,ord(t[1])-96]:=0;
            q[0,ord(t[1])-96,ord(t[1])-96]:=0;
            for i:=1 to len do
            begin
                    si:=ord(t[i])-96;
                    for j:=1 to 11 do
                    begin
                            p[i,j]:=min(p[i-1,si]+2,q[i-1,si,si]+2);
                            if (j<>si) and (not mip[i]) then p[i,j]:=min(p[i,j],p[i-1,j]);
                            if (j<>si) then p[i,j]:=min(p[i,j],q[i-1,si,j]);
                            for k:=1 to 11 do
                            begin
                                    q[i,j,k]:=min(p[i-1,si]+5,q[i-1,si,si]+5);
                                    if (j<>si) then q[i,j,k]:=min(q[i,j,k],min(p[i-1,j]+3,q[i-1,j,si]+3));
                                    if (k<>si) then q[i,j,k]:=min(q[i,j,k],q[i-1,si,k]+3);
                                    if (j<>si) and (k<>si) then q[i,j,k]:=min(q[i,j,k],q[i-1,j,k]+1);
                            end;
                    end;
            end;
            writeln(m*2-2+p[len-1,11]);
    end.
    
  • 相关阅读:
    CSS3边框与圆角
    测试
    linux 日常高逼格命令统计
    python 获取目录视频时长,大小
    记一次 irqbalance: WARNING, didn't collect load info for all cpus, balancing is broken问题
    loging模块
    修改CentOS7系列网卡名称为传统名称eth0格式
    ELK测试
    linux安装python3-pip3-django的过程
    17.基于scrapy-redis两种形式的分布式爬虫
  • 原文地址:https://www.cnblogs.com/RainbowCrown/p/11153777.html
Copyright © 2020-2023  润新知