zoukankan      html  css  js  c++  java
  • Best Reward HDU

    Best Reward

     HDU - 3613

    题意:每个小写字母对应有一个价值,给一个小写字母组成的串s,现在要把s切割成两段,如果切割后的串是回文串,那么价值就是该段所有字母的价值之和,问总价值最大多少。

    用manacher找到前缀回文和后缀回文,枚举切点更新最大之即可。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int inf=0x3f3f3f3f;
     4 const int maxn=500000+10;
     5 char s[maxn<<1];
     6 int r[maxn<<1],sum[maxn],val[27];
     7 int per[maxn],pos[maxn];//per标记前i个字符为回文串,pos标记后i个字符为回文串
     8 
     9 int main(){
    10     int T;
    11     scanf("%d",&T);
    12     while(T--){
    13         for(int i=0;i<26;++i)scanf("%d",&val[i]);
    14         scanf("%s",s);
    15         int len=strlen(s);
    16         sum[0]=val[s[0]-'a'];
    17         for(int i=1;i<len;++i) sum[i]=sum[i-1]+val[s[i]-'a'];
    18         for(int i=len;i>=0;--i){
    19             s[i+i+2]=s[i];
    20             s[i+i+1]='#';
    21         }
    22         s[0]='*';
    23         int id=0;
    24         for(int i=2;i<len+len+1;++i){
    25             if(r[id]+id>i) r[i]=min(r[2*id-i],r[id]+id-i);
    26             else r[i]=1;
    27             while(s[i-r[i]] == s[i+r[i]]) ++r[i];
    28             if(id+r[id]<i+r[i]) id=i;
    29             if(i-r[i]==0) per[r[i]-1]=T+1;//表示前缀(前r[i]-1个字符)是回文串
    30             if(i+r[i]==len+len+2) pos[r[i]-1]=T+1;//表示后缀(后r[i]-1个字符)是回文串
    31         }
    32         int ans=0;
    33         for(int i=1;i<len;++i){
    34             int temp=0;
    35             if(per[i]==T+1) temp+=sum[i-1];
    36             if(pos[len-i]==T+1) temp+=sum[len-1]-sum[i-1];
    37             ans=max(ans,temp);
    38         }
    39         printf("%d
    ",ans);
    40     }
    41     return 0;
    42 }
    View Code

    另解:扩展KMP

  • 相关阅读:
    剑指offer-用两个栈实现队列
    Java数组判空的正确打开方式
    浏览器输入URL后后的过程
    HTTP状态码
    HTTP和HTTPS
    北京好未来公司linux面试题
    三剑客 -- sed
    三剑客 -- grep
    shell脚本
    自动化 -- expect
  • 原文地址:https://www.cnblogs.com/yijiull/p/7410930.html
Copyright © 2011-2022 走看看