题意:
给N个长度,M个单词,每个单词有权值
输出长度不大于N的权值和最大的单词
代价相同输出长度短的,长度相同输出字典序最小
思路:
开一个字符串数组,暴力存储每个节点的单词!
其他思路和dp都一样
注意:如果和为零的话输出空串。
代码:
#include"cstdlib"
#include"cstdio"
#include"cstring"
#include"cmath"
#include"queue"
#include"algorithm"
#include"iostream"
using namespace std;
int triecont;
char fuck[55][1234][55];
struct word
{
char x[12];
int k;
} w[123];
struct trie
{
int mark,id;
trie *next[27],*fail;
trie()
{
mark=id=0;
memset(next,0,sizeof(next));
fail=NULL;
}
};
trie *root,*node[2340];
void init(char *v,int k)
{
trie *p=root;
for(int i=0;v[i];i++)
{
int tep=v[i]-'a';
if(p->next[tep]==NULL)
{
p->next[tep]=new trie();
node[triecont]=p->next[tep];
p->next[tep]->id=triecont++;
}
p=p->next[tep];
}
p->mark+=k;
}
void getac()
{
queue<trie*>q;
q.push(root);
while(!q.empty())
{
trie *p=q.front();
q.pop();
for(int i=0;i<26;i++)
{
if(p->next[i]==NULL)
{
if(p==root) p->next[i]=root;
else p->next[i]=p->fail->next[i];
}
else
{
if(p==root) p->next[i]->fail=root;
else p->next[i]->fail=p->fail->next[i];
q.push(p->next[i]);
if(p!=root) p->next[i]->mark+=p->next[i]->fail->mark;
}
}
}
}
int cmp(char *a,char *b)
{
int len1=strlen(a);
int len2=strlen(b);
if(len1!=len2)
{
if(len1<len2) return 1;
return 0;
}
else
{
if(strcmp(a,b)<0) return 1;
return 0;
}
}
int dp[55][1234];
int main()
{
int t;
cin>>t;
while(t--)
{
int n,m;
scanf("%d%d",&n,&m);
memset(node,0,sizeof(node));
triecont=0;
root=new trie();
node[triecont]=root;
root->id=triecont++;
for(int i=0; i<m; i++) scanf("%s",w[i].x);
for(int i=0; i<m; i++) scanf("%d",&w[i].k);
for(int i=0; i<m; i++)
{
init(w[i].x,w[i].k);
}
getac();
memset(dp,-1,sizeof(dp));
dp[0][0]=0;
char ans[55];
strcpy(fuck[0][0],"");
strcpy(ans,"");
int Max=0;
for(int i=1;i<=n;i++)
{
for(int j=0;j<triecont;j++)
{
if(dp[i-1][j]==-1) continue;
for(int k=0;k<26;k++)
{
trie *p=node[j]->next[k];
int sum=dp[i-1][j]+p->mark;
char tep[55];
strcpy(tep,fuck[i-1][j]);
int len=strlen(tep);
tep[len]='a'+k;
tep[len+1]='\0';
if(sum>dp[i][p->id] || (sum==dp[i][p->id] && cmp(tep,fuck[i][p->id])))
{
dp[i][p->id]=sum;
strcpy(fuck[i][p->id],tep);
if(sum>Max || (sum==Max && cmp(tep,ans)))
{
Max=sum;
strcpy(ans,tep);
}
}
}
}
}
puts(ans);
}
return 0;
}