標籤:io os ar for sp on 代碼 amp new
題意:
給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;}
[AC自動機+dp+記錄路徑] hdu 2825 Ring