鄭廠長系列故事——新聞淨化 AC自動機 DP

來源:互聯網
上載者:User
#include <cstdio>#include <cstring>#include <deque>#define max(a,b) ((a) > (b) ? (a) : (b))#define min(a,b) ((a) < (b) ? (a) : (b))using namespace std;const int LMT = 102;const int SIZE = 656;const int STAT = 256;const int inf = 10000000;const int wiz = 26;int del[2][SIZE][STAT], val[2][SIZE][STAT], siz, word;int gra[SIZE][wiz], fail[SIZE];/**********搞清楚要求的是什麼啊。。。這裡最重要的是del。前狀態其實已經可以從tire樹中取得,不用再確定當前字元所接的前一個字元的位置。這種題目直接YY成圖中的遍曆似乎會好很多。偷看了cxlove神的代碼,羞愧啊...這種題裡其實有兩種遞推關係,一種是tire樹中遍曆,以當前所在節點為狀態還有一種是尋找當前字母在字串中的前字元,大神果斷選了第一種,可是我居然把兩種都選了,以至於想不出啊**********/struct __node{    bool can;    int point, state;}node[SIZE];void init(void){    int i, j, k;    siz = 1;    word = 0;    memset(gra, 0, sizeof(gra));    memset(fail, 0, sizeof(fail));    for(i = 0; i< 2; ++i)         for(j = 0; j < SIZE; ++j)            for(k =0; k < STAT; ++k)            {                del[i][j][k] = inf;                val[i][j][k] = -inf;            }    for(i = 0; i < SIZE; ++i)    {        node[i].point = node[i].state = 0;        node[i].can = 1;    }}void insert(char sec[],const int &__point){    int i, current, index;    for(current = 0, i = 0; sec[i]; ++i)    {        index = sec[i] - 'a';        if (!gra[current][index])            gra[current][index] = siz++;        current = gra[current][index];    }    if(__point != 999 && __point != -999)    {      node[current].can = 1;      node[current].point += __point;    }    else if(__point == 999)    {        node[current].can = 1;         node[current].state |= 1 << (word++);    }    else node[current].can = 0;}void build_ac(void)    {        int current,v;        deque<int>q;        q.clear();        for(int i=0;i<wiz;i++)        if(gra[0][i])q.push_back(gra[0][i]);        while(!q.empty())        {            current=q.front();            q.pop_front();            for(int i = 0;i < wiz;++i)            if(gra[current][i])            {                v = gra[current][i];                fail[v] = gra[fail[current]][i];            node[v].can &= node[fail[v]].can;            node[v].point += node[fail[v]].point;            node[v].state |= node[fail[v]].state;            q.push_back(v);            }            else gra[current][i] = gra[fail[current]][i];        }    }int main(void){    char str[LMT];    int T, n, g,lim, i, ans, value, current, index, state, I = 1;    scanf("%d", &T);    while(T--)    {        init();        lim = 0;ans = inf;        scanf("%d",&n);        while(n--)        {            scanf("%s%d", str, &g);            insert(str,g);        }        build_ac();        lim = (1 << word) -1;        str[0] = 5;        scanf("%s", &str[1]);        del[0][0][0] = 0;        val[0][0][0] = 0;        for(i = 1;str[i]; ++i)        {            for(current = 0; current < siz; ++current)                for(state = 0; state <= lim; ++state)                {                    del[i & 1][current][state] = del[(i + 1) & 1][current][state] + 1;//刪除當前字元,節點不變                    val[i & 1][current][state] = val[(i + 1) & 1][current][state];                }            for(current = 0; current < siz; ++current)                for(state = 0; state <=lim; ++state)                {                    index = gra[current][str[i] - 'a'];                    if (!node[index].can ||                           del[(i + 1) & 1][current][state] >= inf)continue;                    if (del[i & 1][index][state | node[index].state]                         > del[(i + 1) & 1][current][state])                    {                        del[i & 1][index][state | node[index].state] = del[(i + 1) & 1][current][state];                        val[i & 1][index][state | node[index].state] = val[(i + 1) & 1][current][state] + node[index].point;                    }                    else if (del[i & 1][index][state | node[index].state]                         == del[(i + 1) & 1][current][state] &&                    val[i & 1][index][state | node[index].state]                     < val[(i + 1) & 1][current][state] + node[index].point                        )                        val[i & 1][index][state | node[index].state] = val[(i + 1) & 1][current][state] + node[index].point;                }        }                for(current = 0; current < siz; ++current)                        if (ans > del[(i + 1) & 1][current][lim])                        {                            ans = del[(i + 1) & 1][current][lim];                            value = val[(i + 1) & 1][current][lim];                        }                        else if (ans == del[(i + 1) & 1][current][lim]                            && value < val[(i + 1) & 1][current][lim])                            value = val[(i + 1) & 1][current][lim];                        printf("Case %d: ", I++);                        if (ans >= inf)                            printf("Banned\n");                        else printf("%d %d\n", ans, value);    }  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.