HDU 6086 AC自動機 狀壓dp

2021-08-06 04:00:38 字數 2193 閱讀 2842

給出m個單詞,要構造出長度為2*l的包含這全部m個單詞的字串,並且保證這個字串非對稱,其中字元只包括0和1,問一共有多少種構造方法。

在2825的基礎上,本題增加了非對稱的性質,很顯然,只要確定了一半,另一半就固定了。比賽的時候想到了只構造右半邊,要將子串列舉斷點對折來看,但是當時想的是從中間到兩邊的dp,每次直接將對折的兩半字串都加到ac自動機中,本以為這樣就可以處理經過中軸線的子串,但是這樣有問題,因為如011,拆成0和11,如果將11放入ac自動機中,那麼不能保證11一定是在字串中間的(右半邊最左邊),有可能存在***11***這樣的情況。然後覺得可能在單詞結點上處理在某些情況下dp到這個結點才算找到這個單詞,但是每個子串的長度都不一樣,沒有想到怎麼處理。

賽後看了別人的思路,其實與之前說的都差不多,但是只是在dp的時候在l-1的時候才計算那些經過中軸線的字串,想了很久很久,不明白為什麼可以這樣處理,最後終於弄懂了。

對這題來說,首先要分成一半來考慮,這裡不妨考慮左半部分長度為l的字串的構造。那麼所有單詞一共有三種情況,要麼出現在考慮的左半部分,或者出現在右半部分,或者左右各有一部分(經過中軸線),只出現在左邊和右邊的很好處理,只要將單詞串和單詞串翻轉取反加入ac自動機dp即可。

對於經過中軸線的單詞,比如: 011分割成0和11,(注意這裡不能分成01和1,因為這樣就對稱了。)補齊之後是00 | 11,也就是說只要左半部分出現了00,就代表構造的2 * l的字串中已經出現了0011。關鍵是這裡00和11在構造出來的字串中一定要連在一起,其實也就是構造的左半部分的結尾,因此,只要在dp到長度為l的時候才可以考慮這些經過中軸線的字串。

這樣只要在ac自動機中設定兩個單詞結點標記end1和end2,end1表示不經過中軸線的結點,end2表示經過中軸線的單詞結點。dp的時候特判一下進行狀態轉移即可。

比賽的時候思路是從中間向兩邊dp,正解的思路是從兩邊向中間dp,在最後的時刻特殊處理中軸線單詞就行了,仔細想想為什麼前者不行,後者就可以處理,個人認為可能是因為ac自動機的結點表示是一種結尾資訊,也就是到達這個點的表示的資訊,因此不好處理從起點開始的性質,因此需要將問題轉化為到達的性質才可以。

ps:用bc官方題解的暴力列舉思路寫的**一直t到姥姥家。(應該是我太菜了)

#include 

using

namespace

std;

typedef

long

long ll;

const

int maxnode = 2500;

const

int sigma_size = 2;

const ll mod = 998244353;

struct acauto

void init()

void insert1(char *buf, int id)

end1[now] |= (1

<< id);

}void insert2(char *buf, int id)

end2[now] |= (1

<< id);

}void build()

}while (!q.empty()) }}

}} ac;

int n, l;

char s[30], t[30], str[60];

ll dp[2][2500][(1

<< 6) + 10];

int main()

}if (!flag) continue;

reverse(s1.begin(), s1.end());

//cout << " -- " << s1 << endl;

for (int k = (j + 1) * 2; k < len; k++)

//cout << s1 << endl;

strcpy(str, s1.c_str());

ac.insert2(str, i);}}

ac.build();

memset(dp, 0, sizeof(dp));

dp[0][0][0] = 1;

for (int i = 0; i < l; i++)

dp[i % 2][j][s] = 0;}}

}ll ans = 0;

for (int i = 0; i < ac.sz; i++)

printf("%i64d\n", ans);

}return

0;}

hdu 2825 AC自動機 狀壓dp

假設乙個字串長為n,現在在j這個位置,此時已經包含了乙個模式串集合 由於m只有10,所有可以用狀壓來表示模式串 到下乙個位置時,一共有26種情況,現在你想知道的是多乙個字母後會多幾個模式串,由於是多匹配問題便想到了ac自動機,而此時只要紀錄走道j這個位置時trie上走到k這個位置。所以狀態便是dp ...

HDU 2825 AC自動機 狀壓DP

給m個字串,要求組成乙個長度為n的字串,至少包含k個給定字串。利用ac自動機,我們可以進行狀態轉移,以及模板匹配。要求目標串長度為n,且包含k個給定字串。所以可以在包含給定字串的ac自動機上進行狀態轉移。dp i 1 u last u s dp i 1 u last u s dp i j s mod...

HDU 3247 AC自動機 狀壓DP

乙個n個資源串,m個病毒串。要求生成乙個字串,包含所有資源串,但不能包含病毒串。問生成字串的最小長度。首先利用ac自動機求出資源串的狀態轉移關係,因為資源串最多只有十種,因此可以進行狀態壓縮。在利用ac自動機求失配關係的時候 這裡在求失配關係的時候需要將不存在的邊補上 順便求出來狀態包含關係。求出失...