hdu 2296 AC自動機+dp+路徑記錄

來源:互聯網
上載者:User
Ring
#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <vector>#include <queue>using namespace std;#define pb push_back#define INF (1<<30)struct node{    int son[26],fail;    int cnt;    char key;    node(){memset(son,0,sizeof(son));fail=0;cnt=0;}    node(char k):key(k){memset(son,0,sizeof(son));fail=0;cnt=0;}};vector<node> ac;int hash[256];int dp[51][2000];int n,m,T;string key[51][2000];//我採取了暴力做法,記錄每條路徑上的全部字元.另外一種做法是將字串顛倒,只記錄前驅.void init() {    for(int i=0;i<26;++i) hash['a'+i]=i;}void insert(const char *str,int num) {    int p=0,i=0;    while(str[p]) {        if(!ac[i].son[hash[str[p]]]) {            ac[i].son[hash[str[p]]]=ac.size();            ac.pb(node(str[p]));        }        i=ac[i].son[hash[str[p]]];        ++p;    }    ac[i].cnt=num;}void getFail() {    queue<int> qu;    qu.push(0);    while(!qu.empty()) {        int cur=qu.front();qu.pop();        for(int i=0;i<26;++i) {            int nex=ac[cur].son[i];            int p=ac[cur].fail;            if(nex) {//以下這部分實際上提供了另一種求fail的方法                qu.push(nex);                if(~p) ac[nex].fail=ac[p].son[i],ac[nex].cnt+=ac[ac[p].son[i]].cnt;                else ac[nex].fail=0;            }            else {//新的fail求法的關鍵是這一步,它保證每個兒子指標都指向某個節點                if(~p) ac[cur].son[i]=ac[p].son[i];//空兒子不是指向根,就是指向實兒子            }        }    }}char str[101][20];int main() {    ios::sync_with_stdio(false);    init();    cin >> T;    while(T--) {        cin >> n >> m;        ac.clear();        ac.pb(node('a'));        ac[0].fail=-1;        for(int i=0;i<m;++i) cin >> str[i];        for(int i=0;i<m;++i) {            int val;            cin >> val;            insert(str[i],val);        }        getFail();        for(int i=0;i<=n;++i)            for(int j=0;j<ac.size();++j)                dp[i][j]=-1,key[i][j].resize(60,'z');        dp[0][0]=0;        key[0][0]="";        int ans=0,ansi=0,ansj=0;        for(int i=0;i<n;++i)            for(int j=0;j<ac.size();++j) {                if(dp[i][j]==-1) continue;                for(int p=0;p<26;++p) {                    int son=ac[j].son[p];                    if(dp[i+1][son]<dp[i][j]+ac[son].cnt                       ||(dp[i+1][son]==dp[i][j]+ac[son].cnt&&key[i+1][son]>key[i][j]+char('a'+p))) {                        dp[i+1][son]=dp[i][j]+ac[son].cnt;                        key[i+1][son]=key[i][j]+char('a'+p);                    }                    if(dp[i+1][son]>ans||(dp[i+1][son]==ans&&i+1==ansi&&key[i+1][son]<key[ansi][ansj])) {                        ans=dp[i+1][son];                        ansi=i+1;ansj=son;                    }                }            }        cout << key[ansi][ansj] << endl;    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.