• 解题:CF1063F String Journey


    题面

    分析性质以进行DP

    性质1:一定有一个最优解通过每次删除第一个或最后一个字符达到

    这个脑补一下就能证明了

    那么我们设$dp[i]$表示后缀$[i,n]$选出一个前缀所能达到的最大长度,从右往左DP

    转移时二分当前DP值$dp[i]$,在右边找有没有大于等于$f_i-1$且是$[i,n]$前缀/后缀的DP值,具体怎么找就看个人了

    可以不二分吗?可以,继续分析得到性质2

    性质2:dp[i]<=dp[i+1]+1

    反证,如果$dp[i]>dp[i+1]+1$,那么删掉第一个字符,就会得到$dp[i+1]>dp[i+1]+1-1$

    然而不想(hui)写后缀结构的我选择了暴力查哈希,因为答案不会超过$sqrt n$,所以从小到大枚举长度做即可 

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define uint unsigned int
     5 using namespace std;
     6 const int N=500005;
     7 const uint mod=7539151;
     8 bool p1[N],p2[N],mp[mod+1]; 
     9 uint hsh[N]; char str[N]; int n; 
    10 int main()
    11 {
    12     register int i,j;
    13     scanf("%d%s",&n,str+1);
    14     bool *dp=p1,*pd=p2; 
    15     int ans=1,lim=min(1000,n);
    16     for(i=1;i<=n;i++) 
    17         hsh[i]=str[i]-'a'+1,pd[i]=true;
    18     for(i=2;i<=lim;swap(dp,pd),i++)
    19     {
    20         memset(dp,0,sizeof p1);
    21         memset(mp,0,sizeof mp);
    22         for(j=n-i+1;j;j--)
    23         {
    24             if(j+i<=n&&pd[j+i]) mp[hsh[j+i]]=true;
    25             if(mp[hsh[j]]||mp[hsh[j+1]]) ans=i,dp[j]=true;
    26         }
    27         for(j=1;j<=n-i+1;j++)
    28             hsh[j]=(hsh[j]*233+str[j+i-1]-'a'+1)%mod;
    29     }
    30     printf("%d",ans);
    31     return 0;
    32 }
    View Code
  • 相关阅读:
    django email用法
    django ImageField用法
    django集成微博内容
    python读写zip文件
    读写文件
    404渲染
    bzoj1297 / P4159 [SCOI2009]迷路
    bzoj1009 / P3193 [HNOI2008]GT考试
    poj2115 C Looooops(exgcd)
    bzoj1407 / P2421 [NOI2002]荒岛野人(exgcd)
  • 原文地址:https://www.cnblogs.com/ydnhaha/p/10534938.html
Copyright © 2020-2023  润新知