hdu2296

来源:互联网 发布:光纤网络布线方案 编辑:程序博客网 时间:2024/05/22 00:49

今天机房断网,结果回来才交果不其然WA掉了。然后又是各种调各种弄,最后竟然A了。真是畸形。个人觉得字符串上的DP基本都是按照字符串的位进行的。当然我也没有做几道题。这个也是一个很简单的DP但是对于预处理方面可能需要考虑一下,以及它最后的要求是输出字典序最小。而且之前也没有看到最后答案可能会有空串什么的,改了就过了。

上代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
using namespace std;
struct node{
    node *fail;
    node *next[26];
    int count;
    int id;
    bool end;
    int v;
    int ss;
    node(){
        id=0;
        end=false;
        fail=NULL;
        count=0;
        v=0;
        for(int i=0;i<=25;i++)
            next[i]=NULL;
    }
};
struct sstring{
    char s1[60];
};
sstring s[1110];
bool cmp(sstring a, sstring b){
    if(strlen(a.s1)==strlen(b.s1))
    return strcmp(a.s1,b.s1)<0;
    return strlen(a.s1)<strlen(b.s1);
}


const int MAXN=1110;
node *T[1110];
node *q[MAXN];
node *root=new node();
int num=1;
void insert(char word[],int value){
    node *cur=root;
    int i=0,branch;
    while(word[i]){
        branch=word[i]-'a';
        if(cur->next[branch]==NULL){
            cur->next[branch]=new node();
            T[num]=cur->next[branch];
            T[num]->ss=branch;
            cur->next[branch]->id=num++;
        }
        i++;
        cur=cur->next[branch];
    }


    cur->v=value;
    cur->end=true;
    cur->count++;
}
void AC(){
    int rear=1,front=0,i;
    node *cur;
    q[0]=root;
    root->fail=root;
    while(front!=rear){
        node *p=q[front++];
        p->end=p->end||p->fail->end;
        for(int i=0;i<=25;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[rear++]=p->next[i];
            }
        }
    }
}
char a[110][20];
int dp[60][1110];
int pre[60][1110];
int g[MAXN][MAXN];
int vis[60][1110];
main(){
    int t,n,m;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        root=new node();
        num=1;
        for(int i=1;i<=m;i++){
            scanf("%s",a[i]);
        }
        for(int i=1;i<=m;i++){
            int cnt;
            scanf("%d",&cnt);
            insert(a[i],cnt);
        }
        AC();
        T[0]=root;
        root->id=0;
        root->ss=30;
        memset(dp,0,sizeof(dp));
        memset(pre,0,sizeof(pre));
        memset(vis,0,sizeof(vis));
        for(int k=0;k<=25;k++){
            if(T[0]->next[k]!=NULL){
                if(T[0]->next[k]->id!=0){
                    dp[1][T[0]->next[k]->id]=T[0]->next[k]->v;
                    vis[1][T[0]->next[k]->id]=1;
                }
                }
            }
            dp[1][0]=0;
        for(int i=1;i<=n-1;i++){
            for(int j=0;j<num;j++){
                if(vis[i][j]){
                for(int k=0;k<=25;k++){
                    if(T[j]->next[k]!=NULL){
                        if(dp[i+1][T[j]->next[k]->id]<=dp[i][j]+T[j]->next[k]->v){
                            vis[i+1][T[j]->next[k]->id]=1;
                            if(dp[i+1][T[j]->next[k]->id]==(dp[i][j]+T[j]->next[k]->v) && dp[i+1][T[j]->next[k]->id]!=0){
                                int p=j;
                                char pp[2][20];
                                pp[0][i]=0;
                                for(int kk=i-1;kk>=0;kk--){
                                    pp[0][kk]=T[p]->ss+'a';
                                    p=pre[kk+1][p];
                                }
                                p=pre[i+1][T[j]->next[k]->id];
                                pp[1][i]=0;
                                for(int kk=i-1;kk>=0;kk--){
                                    pp[1][kk]=T[p]->ss+'a';
                                    p=pre[kk+1][p];
                                }
                                if(strcmp(pp[0],pp[1])<0)
                                    pre[i+1][T[j]->next[k]->id]=j;
                            }
                            else{
                                pre[i+1][T[j]->next[k]->id]=j;
                                dp[i+1][T[j]->next[k]->id]=dp[i][j]+T[j]->next[k]->v;
                            }
                        }
                    }
                }
            }
            }
        }
        int nnum=0;
        int maxx=0;
        for(int i=1;i<=n;i++){
        for(int j=0;j<num;j++){
            //printf("%d ",dp[i][j]);
            if(dp[i][j]>maxx){
                maxx=dp[i][j];
            }
        }
        }
        for(int j=1;j<=n;j++){
        for(int i=0;i<num;i++){
            if(dp[j][i]==maxx){
                int p=i;
                s[nnum].s1[j]=0;
                for(int k=j-1;k>=0;k--){
                    s[nnum].s1[k]=T[p]->ss+'a';
                    p=pre[k+1][p];
                }
                nnum++;
            }
        }
        }
        sort(s,s+nnum,cmp);
        if(maxx==0)
        printf("\n");
        else
        printf("%s\n",s[0].s1);
    }
}

原创粉丝点击