HDU 3613Best Reward(擴充KMP解法)

來源:互聯網
上載者:User
Best Reward

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 406    Accepted Submission(s): 167


Problem DescriptionAfter an uphill battle, General Li won a great victory. Now the head of state decide to reward him with honor and treasures for his great exploit. 

One of these treasures is a necklace made up of 26 different kinds of gemstones, and the length of the necklace is n. (That is to say: n gemstones are stringed together to constitute this necklace, and each of these gemstones belongs to only one of the 26 kinds.) 

In accordance with the classical view, a necklace is valuable if and only if it is a palindrome - the necklace looks the same in either direction. However, the necklace we mentioned above may not a palindrome at the beginning. So the head of state decide to
cut the necklace into two part, and then give both of them to General Li. 

All gemstones of the same kind has the same value (may be positive or negative because of their quality - some kinds are beautiful while some others may looks just like normal stones). A necklace that is palindrom has value equal to the sum of its gemstones'
value. while a necklace that is not palindrom has value zero. 

Now the problem is: how to cut the given necklace so that the sum of the two necklaces's value is greatest. Output this value. 

 


InputThe first line of input is a single integer T (1 ≤ T ≤ 10) - the number of test cases. The description of these test cases follows. 

For each test case, the first line is 26 integers: v1, v2, ..., v26 (-100 ≤ vi ≤ 100, 1 ≤ i ≤ 26), represent the value of gemstones of each kind. 

The second line of each test case is a string made up of charactor 'a' to 'z'. representing the necklace. Different charactor representing different kinds of gemstones, and the value of 'a' is v1, the value of 'b' is v2, ..., and so on.
The length of the string is no more than 500000. 

 


OutputOutput a single Integer: the maximum value General Li can get from the necklace. 


Sample Input

21 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1aba1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1acacac
 


Sample Output

16
                    題目大意:題目意思還是比較容易懂的。小寫字母a~z組成的長n的串, 每種字母有一定的價值(可以為負), 要你分成切成兩個串, 總價值為兩個串價值和,
若是迴文, 則串的價值為每個字母價值和, 否則為0。 問最大價值多少。
           
解題思路:可以將原串逆序到另一串,然後兩個串相互EKMP匹配,比如str1與str2。先看str2的後半部分能否和str1前面的完全符合,如果可以tmp+。再判斷這個的時候還要判斷str1的後面能否和str2前面是否匹配,這就需要進行兩次的EKMP。具體詳見代碼。思路來源於kuangbin.
           
題目地址:Best Reward
AC代碼:
#include<iostream>#include<cstring>#include<string>#include<cmath>#include<cstdio>using namespace std;char str1[500005],str2[500005];int next[500005],extend1[500005],extend2[500005];int v[26],sum[500005];//擴充KMP是用來求主串每個點可以向後延伸與模式串匹配的最長的長度void EKMP(char t[],char s[],int next[],int extend[]){   //t為模式串,s為主串    int i,j,p,a,b;    int lent=strlen(t);    int lens=strlen(s);    next[0]=lent; j=0;    while(j+1<lent&&t[j]==t[j+1])        j++;    next[1]=j;  //先是模式串自匹配    a=1;    for(i=2;i<lent;i++)    {        p=next[a]+a-1;        b=next[i-a];        if(i+b<p+1)            next[i]=b;        else        {            j=max(0,p-i+1);            while(i+j<lent&&t[i+j]==t[j])                j++;            next[i]=j;            a=i;        }    }    j=0;    while(j<lens&&j<lent&&s[j]==t[j])        j++;    extend[0]=j;    a=0;    for(i=1;i<lens;i++)    {        p=extend[a]+a-1;        b=next[i-a];        if(i+b<p+1)            extend[i]=b;        else        {            j=max(0,p-i+1);            while(i+j<lens&&j<lent&&s[i+j]==t[j])                j++;            extend[i]=j;            a=i;        }    }}int main(){    int tes,i;    scanf("%d",&tes);    while(tes--)    {        for(i=0;i<26;i++)            scanf("%d",&v[i]);        scanf("%s",str1);        int len=strlen(str1);        sum[0]=0;        for(i=0;i<len;i++)        {            str2[i]=str1[len-1-i];            sum[i+1]=sum[i]+v[str2[i]-'a'];        }        str2[len]='\0';        EKMP(str1,str2,next,extend1);  //str1是模式串        EKMP(str2,str1,next,extend2);  //str2是模式串        int res=-1000000;        for(i=1;i<len;i++)  //0~i-1與i~len-1        {            int tmp=0;            //對串2來說,前len-i迴文            if(i+extend2[i]>=len)                tmp+=sum[len-i];            int pos=len-i;            //對串2來說,後i個迴文            if(pos+extend1[pos]>=len)                tmp+=sum[len]-sum[pos];            if(tmp>res)                res=tmp;        }        printf("%d\n",res);    }    return 0;}

             

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.