zoukankan      html  css  js  c++  java
  • AtCoder2698 Don't Be a Subsequence(dp+序列自动机)

    考虑倒序dp

    设计状态f[i]为到末尾的最小不存在子序列。

    首先如果后面没有某个字母,那么答案就是1

    不然的话必然要在首位加上一个字母。

    考虑枚举所有情况,也就是第一个字母填什么,这样就是全部答案。

    如果直接枚举后面每个位置更新,复杂度太高,我们想到维护一个后缀,表示每个字母在i和之后出现的第一个位置pos是哪就行

    这是因为i-那个位置之间只有一个当前字母,由于越后面的状态答案越小,因此我们以这个字母开头,那么答案就是1+f[pos+1],因为f[pos+1]就是到终点的最小串,而我们第一个位置必须填一个字母

    所以这种方案肯定成立,也是最优的。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=2e5+10;
    int nxt[N][26];
    int f[N];
    int main(){
        ios::sync_with_stdio(false);
        int i,j;
        string s;
        cin>>s;
        int n=s.size();
        s=" "+s;
        for(i=n;i>=1;i--){
            for(j=0;j<26;j++){
                if(s[i]-'a'==j){
                    nxt[i][j]=i;
                }
                else{
                    nxt[i][j]=nxt[i+1][j];
                }
            }
        }
        memset(f,0x3f,sizeof f);
        for(i=n;i>=1;i--){
            for(j=0;j<26;j++){
                if(!nxt[i][j]){
                    f[i]=1;
                    break;
                }
                else{
                    f[i]=min(f[i],f[nxt[i][j]+1]+1);
                }
            }
        }
        int now=1;
        int ans=f[1];
        while(ans--){
            for(i=0;i<26;i++){
                if(f[now]==f[nxt[now][i]+1]+1){
                    cout<<char('a'+i);
                    now=nxt[now][i]+1;
                    break;
                }
            }
        }
        for(i=0;i<26;i++){
            if(!nxt[now][i]){
                cout<<char('a'+i);
                break;
            }
        }
        cout<<endl;
        return 0;
    }
    View Code
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    初步认识虚函数(三)
    初步认识虚函数(二)
    C++遍历目录+_finddata_t结构体用法
    初步认识虚函数(一)
    gSOAP 使用WebServer心得
    如何优雅的写UI——(6)内存泄漏
    如何优雅的写UI——(5)选项卡功能实现
    如何优雅的写UI——(4)选项卡美化
    变色字体
    如何优雅的写UI——(3)添加MFC选项卡
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/14688273.html
Copyright © 2011-2022 走看看