zoukankan      html  css  js  c++  java
  • AtCoder Regular Contest 081 E

      引用自:onion_cyc

      字符串DP一直不是强项。。。以后没思路的题就想DP和网络流23333333

      f[i]表示从i开始的后缀非子序列的最短长度  pos[i][j]表示从i开始的j字符最早出现位置

      则有 f[i]=f[pos[i][j]+1]+1   因为1~pos[i][j]这一段只可能出现一次j,后面接一个不是pos[i][j]+1开始的后缀的子序列的字符串,一定也不是i开始的后缀的子序列

      初始状态f[n+1]=1 f[n+2]=0 pos[n+1][0..26]=n+1 因为最后一位的后缀随意添加一个字符一定不是最后一位的后缀的子序列

      对于输出方案显然可以找从哪里转移的

    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    using namespace std;
    const int maxn=500010,inf=1e9;
    int n;
    int pos[maxn][26],f[maxn];
    char s[maxn];
    void read(int &k)
    {
        int f=1;k=0;char c=getchar();
        while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
        while(c<='9'&&c>='0')k=k*10+c-'0',c=getchar();
        k*=f;
    }
    int main()
    {
        scanf("%s",s+1);n=strlen(s+1);
        memset(f,32,(n+1)<<2);f[n+1]=1;f[n+2]=0;
        for(int i=0;i<26;i++)pos[n+1][i]=n+1;
        for(int i=n;i;i--)
        {
            for(int j=0;j<26;j++)
            pos[i][j]=pos[i+1][j];
            pos[i][s[i]-'a']=i;
        }
        for(int i=n;i;i--)
        for(int j=0;j<26;j++)
        f[i]=min(f[i],f[pos[i][j]+1]+1);
        int now=1;
        for(int j=f[1];j;j--)
        for(int i=0;i<26;i++)
        if(f[now]==f[pos[now][i]+1]+1)
        {
            putchar(i+'a');
            now=pos[now][i]+1;
            break;
        }
    }
    View Code
  • 相关阅读:
    ViewData,ViewBag,TempData
    http和https
    Array与ArrayList
    程序员与书和视频
    技术学习的方法研究
    文章发布声明
    面向对象JAVA多态性
    嵌入式开发总结
    CSDN博客代码显示乱码的原因
    将Windows的桌面目录设置到D盘
  • 原文地址:https://www.cnblogs.com/Sakits/p/7428894.html
Copyright © 2011-2022 走看看