HDOJ3613解题报告

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDOJ3613解题报告相关的知识,希望对你有一定的参考价值。

题目地址:

  http://acm.hdu.edu.cn/showproblem.php?pid=3613

题目概述:

  给出一个字符串s以及每个小写字母的价值,现要求将s分为两个部分,对于每部分,如果是回文串则这个子串的价值为所有字母的价值之和,否则为零,请合理分开这个串使总价值最大。

大致思路:

  EX_KMP。其实也是没有看懂啦。

  不过看了下这位大神的BLOG:http://blog.csdn.net/dyx404514/article/details/41831947

  迷迷糊糊的过了……

代码:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstdlib>
  4 #include <cmath>
  5 #include <vector>
  6 #include <ctime>
  7 #include <map>
  8 #include <stack>
  9 #include <queue>
 10 #include <cstring>
 11 #include <algorithm>
 12 using namespace std;
 13 
 14 #define sacnf scanf
 15 #define scnaf scanf
 16 #define maxn  500010
 17 #define maxm 26
 18 #define inf 1061109567
 19 #define Eps 0.00001
 20 const double PI=acos(-1.0);
 21 #define mod 7
 22 #define MAXNUM 10000
 23 void Swap(int &a,int &b) {int t=a;a=b;b=t;}
 24 int Abs(int x) {return (x<0)?-x:x;}
 25 typedef long long ll;
 26 typedef unsigned int uint;
 27 
 28 char s1[maxn],s2[maxn];
 29 int extend1[maxn],extend2[maxn],Next[maxn];
 30 int val[maxm],sum[maxn];
 31 
 32 void Get_Next(char *S,int len)
 33 {
 34     int po=0;
 35     Next[0]=len;
 36     while(po+1<len&&S[po]==S[po+1]) po++;
 37     Next[1]=po;po=1;
 38     for(int i=2;i<len;i++)
 39     {
 40         if(Next[i-po]+i<Next[po]+po) Next[i]=Next[i-po];
 41         else
 42         {
 43             int j=max(0,Next[po]+po-i);
 44             while(i+j<len&&S[j]==S[i+j]) j++;
 45             Next[i]=j;po=i;
 46         }
 47     }
 48 }
 49 
 50 void EKMP(char *S,char *T,int *extend,int len)
 51 {
 52     Get_Next(s1,len);
 53     int po=0;
 54     while(po<len&&S[po]==T[po]) po++;
 55     extend[0]=po;po=0;
 56     for(int i=1;i<len;i++)
 57     {
 58         if(Next[i-po]+i<extend[po]+po) extend[i]=Next[i-po];
 59         else
 60         {
 61             int j=max(0,extend[po]+po-i);
 62             while(i+j<len&&S[i+j]==T[j]) j++;
 63             extend[i]=j;po=i;
 64         }
 65     }
 66 }
 67 
 68 int main()
 69 {
 70     //freopen("data.in","r",stdin);
 71     //freopen("data.out","w",stdout);
 72     //clock_t st=clock();
 73     int T;scanf("%d",&T);
 74     while(T--)
 75     {
 76         for(int i=0;i<26;i++) scanf("%d",&val[i]);
 77         scanf("%s",s1);int len=strlen(s1);sum[0]=0;
 78         for(int i=0;i<len;i++)
 79         {
 80             sum[i+1]=sum[i]+val[s1[i]-a];
 81             s2[len-i-1]=s1[i];
 82         }
 83 
 84         EKMP(s2,s1,extend1,len);
 85         EKMP(s1,s2,extend2,len);
 86 
 87         int ans=0;
 88         for(int i=1;i<len;i++)
 89         {
 90             int temp=0;
 91             if(extend1[len-i]==i) temp+=sum[i];
 92             if(extend2[i]==len-i) temp+=sum[len]-sum[i];
 93             ans=max(ans,temp);
 94         }
 95         printf("%d\n",ans);
 96     }
 97     //clock_t ed=clock();
 98     //printf("\n\nTime Used : %.5lf Ms.\n",(double)(ed-st)/CLOCKS_PER_SEC);
 99     return 0;
100 }

 

以上是关于HDOJ3613解题报告的主要内容,如果未能解决你的问题,请参考以下文章

HDOJ1058解题报告

HDOJ6269解题报告

HDOJ2058解题报告

HDOJ2242解题报告边双连通分量

HDOJ3555解题报告

HDOJ1811解题报告