[AC自动机+dp+记录路径] hdu 2825 Ring

来源:互联网 发布:傲剑丹田升级数据一游 编辑:程序博客网 时间:2024/05/01 03:23

题意:

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


0 0
原创粉丝点击