• codeforces MemSQL start[c]up Round 2


    题目链接:  http://codeforces.com/contest/335/problem/B

    分析: 第一眼看上去串的长度为5*10^4, 冒似只能用O(n)的算法可解. 而这样的算法从来没见过......

          其实不然, 注意一个条件"如果有存在长度为100的回文子串则输出长度为100的,否则输出最长的",

          可以发现: 一个长度大于100的回文串都可以变成长度为100的

          如: 长度为101的只要删除中间的一个就变为长度为100的,

              长度为102的删除中间两个也变为长度为100的......

          意思就是, 得到的结果串的长度一定小于等于100.

          又因为原串中全为小写字母, 所以最多出现26个字母,

         还可以发现, 当长度达到2600时, 肯定会出现长度为100回文子串, 因为肯定会有一个字母出现次数大于等于100

          也就是说, 最终, 我们最后取2600个字母, 那么可以用O(n^2)(这里n<=2600) 算法...........

    代码:

    #include<iostream>
    #include<cstdio>
    #include<string>
    using namespace std;
    const int maxn=2601;
    int dp[maxn][maxn]; ///dp[i][j]表示区间[i,j]中回文子串的长度
    int L[maxn][maxn];
    int R[maxn][maxn];
    int main(){
        
        string s; cin>>s;
        int len=min(maxn,(int)s.size());
        for(int i=0;i<len;++i)  
            dp[i][i]=1;
        for(int i=1; i<len; ++i)
            for(int j=0; j+i<len; ++j) {
                int k=j+i;
                if(dp[j+1][k]>dp[j][k]) {
                    dp[j][k]=dp[j+1][k];
                    L[j][k]=j+1;
                    R[j][k]=k;
                }
                if(dp[j][k-1]>dp[j][k]) {
                    dp[j][k]=dp[j][k-1];
                    L[j][k]=j;
                    R[j][k]=k-1;
                }
                if(s[j]==s[k]&&dp[j+1][k-1]+2>dp[j][k]) {
                    dp[j][k]=dp[j+1][k-1]+2;
                    L[j][k]=j+1;
                    R[j][k]=k-1;
                }
            }
        int ans=min(dp[0][len-1],100);
        char ch[102]="";
        int ls=0, rs=len-1;
        int lc=0, rc=ans-1;
        while(lc<=rc){ 
            if(lc==rc){
                ch[lc]=s[ls]; break;
            }
            if(s[ls]==s[rs]){
                ch[lc]=ch[rc]=s[ls];
                lc++; rc--; 
                ls++; rs--; 
                continue;
            }
            int lx=ls, rx=rs;
            ls=L[lx][rx];
            rs=R[lx][rx];
        }
        cout<<ch<<endl;
        return 0;
    }
    
    
    


  • 相关阅读:
    观察者模式
    如何通过反射创建对象?
    java8新特性
    idea 常用快捷键--标蓝
    java多线程基础篇-01
    zookeeper单机版及操作
    redis和jedis常用api
    Mac连接服务器
    redis基本介绍及安装01
    docker 安装mobsf及部分命令01
  • 原文地址:https://www.cnblogs.com/riskyer/p/3236825.html
Copyright © 2020-2023  润新知