| English Game | 
| description | 
| This English game is a simple English words connection game. | 
| input | 
| There are several test cases. For each test, N (1<=n<=1000) and X (the length of x is not bigger than 10000) are given at first. Then N rows follow. Each row contains a word wi (the length is not bigger than 30) and the weight of it. Every word is composed of lowercases. No two words in the dictionary are the same. | 
| output | 
| For each test case, output the biggest sum weight, if you could not form the string X, output -1. | 
| sample_input | 
| 1 aaaa | 
| sample_output | 
| 8 | 
| hint | 
| source | 
| Time Limit 1000ms | Memory Limit 65536K | 
思路:字典树DP,dp[x+len]=max(dp[x+len,dp[x]])
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
const int mm=1e4+9;
class node
{ public:
node*next[26];
int val;
int word;
node(){memset(next,NULL,sizeof(next));val=word=0;}
}root,*p;
char s[mm],ss[mm];
int dp[mm];
void ins(char*s,int val)
{
p=&root;
int k=0;
while(s[k]!='\0')
{
if(!p->next[s[k]-'a'])
p->next[s[k]-'a']=new node();
p=p->next[s[k]-'a'];
///p->word++;
++k;
}
p->word=1;
p->val=max(val,p->val);
}
void look(char*s,int x)
{
p=&root;
int k=x;
while(s[k]!='\0'&&p->next[s[k]-'a'])
{ p=p->next[s[k]-'a'];
++k;
if(p->word)
dp[k]=max(dp[k],dp[x]+p->val);
}
}
void free_m(node*p)
{
for(int i=0;i<26;++i)
if(p->next[i])
{
free_m(p->next[i]);
p->next[i]=NULL;
}
delete p;
}
int main()
{ int n,val;
///freopen("data.in","r",stdin);
///freopen("dd.txt","w",stdout);
while(~scanf("%d%s",&n,s))
{
for(int i=0;i<n;++i)
{
scanf("%s%d",ss,&val);
ins(ss,val);
}
memset(dp,-1,sizeof(dp));
int len=strlen(s);
dp[0]=0;
for(int i=0;i<len;++i)
if(dp[i]!=-1)
look(s,i);
if(dp[len]!=-1)printf("%d\n",dp[len]);
else printf("-1\n");
node *p=&root;
///delete p;
/**for(int i=0;i<26;++i)
if(p->next[i])
{delete p->next[i];p->next[i]=NULL;}
*/
for(int i=0;i<26;++i)
if(p->next[i])
{free_m(p->next[i]);p->next[i]=NULL;}
}
}









