• HDU 3613 Best Reward(扩展KMP求前后缀回文串)


    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3613 

    题目大意:

    大意就是将字符串s分成两部分子串,
    若子串是回文串则需计算价值,否则价值为0,求分割字符串s能获得的最大价值。

    解题思路:将原串s反转得到rs,然后进行rs,s扩展KMP匹配,得到extend,对于s1的前i个字符如果和s2的后i个字符相等即extend[len-i] == i则前i个字符为回文串;

    同理,判断后len-i个字符是否是回文串用s,rs进行扩展KMP再生成一个extend即可。

    代码

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 const int N=1e6+5;
     7 const int INF=0x3f3f3f3f;
     8 
     9 int nxt[N],extend1[N],extend2[N],val[N],sum[N];
    10 char s[N],rs[N];
    11 
    12 void getnext(char *t){
    13     int a,p,len;
    14     len=strlen(t);
    15     nxt[0]=len;
    16     for(int i=1,j=-1;i<len;i++,j--){
    17         if(j<0||i+nxt[i-a]>=p){
    18             if(j<0)
    19                 p=i,j=0;
    20             while(p<len&&t[p]==t[j])
    21                 p++,j++;
    22             nxt[i]=j;
    23             a=i;
    24         }
    25         else
    26             nxt[i]=nxt[i-a];
    27     }
    28 }
    29 
    30 void ex_kmp(char *s,char *t,int *extend){
    31     int a,p,len1,len2;
    32     len1=strlen(s);
    33     len2=strlen(t);
    34     for(int i=0,j=-1;i<len1;i++,j--){
    35         if(j<0||i+nxt[i-a]>=p){
    36             if(j<0)
    37                 p=i,j=0;
    38             while(p<len1&&j<len2&&s[p]==t[j])
    39                 p++,j++;
    40             extend[i]=j;
    41             a=i;
    42         }
    43         else extend[i]=nxt[i-a];
    44     }
    45 }
    46 
    47 int main(){
    48     int t;
    49     scanf("%d",&t);
    50     while(t--){
    51         for(int i=0;i<26;i++){
    52             scanf("%d",&val[i]);
    53         }
    54         scanf("%s",s);
    55         int len=strlen(s);
    56         for(int i=0;i<len;i++){
    57             rs[len-i-1]=s[i];
    58         }
    59         getnext(rs);
    60         ex_kmp(s,rs,extend1);
    61         getnext(s);
    62         ex_kmp(rs,s,extend2);
    63         for(int i=0;i<len;i++){
    64             sum[i]=val[s[i]-'a'];
    65             if(i!=0)
    66                 sum[i]+=sum[i-1];
    67         }
    68         int ans=-INF;
    69         //枚举分割位置(把s[i]归给前面的子串)
    70         for(int i=0;i<len-1;i++){
    71             int tmp=0;
    72             if(extend2[len-i]==i) tmp+=sum[i];
    73             i++;
    74             if(extend1[i]==len-i) tmp+=sum[len-1]-sum[i-1];
    75             ans=max(ans,tmp);
    76         }
    77         printf("%d
    ",ans);
    78     }
    79     return 0;
    80 }
  • 相关阅读:
    VS2012 打包部署程序
    请求筛选模块被配置为拒绝包含 hiddenSegment 节的 URL 中的路径
    “远程服务器返回错误: (404) 未找到”的正确解决方法
    23.IDEA 运行junit单元测试方法
    Java单元测试之JUnit篇
    22.IntelliJ IDEA 切换 project
    21. 【intellij idea】Project Structure 讲解
    一个多maven项目聚合的实例
    解决Maven项目相互依赖/循环依赖/双向依赖的问题
    20. idea刷新项目、清除项目缓存
  • 原文地址:https://www.cnblogs.com/fu3638/p/8503577.html
Copyright © 2020-2023  润新知