题意:
给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; }
时间: 2024-10-07 05:31:47