Test instructions
Give you n a string, n (1 <= n <= 2w), the length of all strings plus not more than 30w. Each string has a value. This value [-1000, 1000].
Ask not to disturb the string order, take several strings from it, so that the previous string is the substring of the latter string, to satisfy the preceding conditions of the string is worth and maximum, to find this value.
Ideas:
is actually a very obvious DP.
Dp[i] represents the maximum weight at the end of the first string.
But that's the problem with the substring.
Because this data compares water can use suffix array to deal with this problem.
Stitch all the strings and do the SA.
Each time you look up and down in the height array, the common prefix equals the string that corresponds to those suffixes that are greater than or equal to this string length.
Then the state transitions.
The positive solution of this problem should be the AC automata +dp+ segment tree optimization.
Over time to complete the completion.
Suffix Array +DP code:
#include "stdio.h" #include "algorithm" #include "string.h" #include "iostream" #include "queue" #include "map" #include " Vector "#include" string "#define N 340005#define M 20005using namespace Std;int v[n],sa[n],ra[n],height[n],id[n];int wa[ N],wb[n],wv[n],wws[n];char fuck[n];int value[m],mark[m],dp[m],len[m];int cmp (int *r,int a,int b,int l) {return r[a]==r[ B]&&R[A+L]==R[B+L];} void da (int n,int m) {int i,j,p,*x=wa,*y=wb; for (i=0; i<m; i++) wws[i]=0; for (i=0; i<n; i++) wws[x[i]=v[i]]++; for (I=1; i<m; i++) wws[i]+=wws[i-1]; for (i=n-1; i>=0; i--) sa[--wws[x[i]]]=i; For (J=1,p=1, p<n; j*=2,m=p) {for (i=n-j,p=0; i<n; i++) y[p++]=i; for (i=0; i<n; i++) if (sa[i]>=j) y[p++]=sa[i]-j; for (i=0; i<n; i++) wv[i]=x[y[i]; for (i=0; i<m; i++) wws[i]=0; for (i=0; i<n; i++) wws[wv[i]]++; for (I=1; i<m; i++) wws[i]+=wws[i-1]; for (i=n-1; i>=0; i--) sa[--wws[wv[i]]]=y[i]; for (Swap (x, y), p=1,i=1,x[sa[0]]=0; i<n; i++) x[sa[i]]=cmp (y,sa[i],sa[i-1],j) p-1:p++; } return; void Gethei (int n) {int i,j,k=0; for (I=1; i<=n; i++) ra[sa[i]]=i; for (i=0; i<n; i++) {if (k) k--; J=SA[RA[I]-1]; while (V[i+k]==v[j+k]) k++; Height[ra[i]]=k; } return; int main () {int t,cas=1; cin>>t; while (t--) {int n,cnt=0,s=0; scanf ("%d", &n); for (int i=0;i<n;i++) {scanf ("%s%d", Fuck,&value[i]); Dp[i]=value[i]; Len[i]=strlen (Fuck); Each string length mark[i]=s; For each string fetch Rank[mark[i]] is the suffix from which to start s+=len[i]+1; for (int j=0;fuck[j];j++) {id[cnt]=i; Each suffix corresponds to which string of v[cnt++]=fuck[j]-' a '; } id[cnt]=i; v[cnt++]=i+55; } v[cnt]=0; Da (cnt+1,30000); Gethei (CNT); for (int i=0;i<n;i++) {int min=n; For(int j=ra[mark[i]];j>0;j--)//Look up {min=min (min,height[j]); if (Min<len[i]) break; int tep=id[sa[j-1]]; if (tep>i) Dp[tep]=max (Dp[tep],dp[i]+value[tep]); } min=n; for (int j=ra[mark[i]]+1;j<=cnt;j++)//down {min=min (min,height[j]); if (Min<len[i]) break; int Tep=id[sa[j]]; if (tep>i) Dp[tep]=max (Dp[tep],dp[i]+value[tep]); }} int ans=0; for (int i=0;i<n;i++) Ans=max (Ans,dp[i]); printf ("Case #%d:%d\n", Cas++,ans); } return 0;}
[Suffix array +dp/ac automaton +dp+ segment tree] hdu 4117 GRE Words