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;}
}
}