HDU 2825 AC自動機 狀壓DP

2021-08-06 00:09:55 字數 1489 閱讀 8629

給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;

dp[i][j][k]表示,第i步,在j節點,已經包含的字串狀態為k。針對每乙個在條件範圍內的i,j,k都可以進行狀態轉移。最後統計一下i==n時包含字串狀態對應的字串個數大於k的狀態之和即為所求。

#include 

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define up(i,l,h) for(int i=l;i#define down(i,h,l) for(int i=h-1;i>=l;i--)

#define w(a) while(a)

#define mem(a,b) memset(a,b,sizeof(a))

#define inf 0x3f3f3f3f3f3f3f3f

#define ll long long

#define ull unsigned long long

#define maxn 10000

#define eps 1e-10

#define mod 20090717

#define n 26

using

namespace

std;

int n,m,k;

int ch[110][26];

char st[15];

int sz,num;

int val[110],hasnum[1050],f[110],last[110];

int dp[30][110][1050];

void insert()

u=ch[u][x];

}val[u]=1

}}void getfail()

}w(!q.empty())

q.push(u);

int v=f[r];

f[u]=ch[v][i];

// cout}

}}int main()

getfail();

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

up(i,0,n) }}

}int ans=0;

up(i,0,sz) }}

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

}}/*

2 2 1

abcbcd

1 1 1

a*/

hdu 2825 AC自動機 狀壓dp

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

hdu2825 (AC自動機 狀壓DP)

題解 ac自動機,然後在自動機上跑一遍dp,第一維表示長度,第二維表示到達自動機上的哪乙個結點,第三維用二進位制表示有含有哪幾個字元 然後轉移方程就是 dp i 1 ret k v ret dp i 1 ret k v ret dp i j k mod 有些dp i j k 等於0就不用運算了 in...

hdu2825 ac自動機 狀壓dp

傳送門 給你一些密碼片段字串,讓你求長度為n,且至少包含k個不同密碼片段串的字串的數量。因為密碼串不多,可以考慮狀態壓縮 設dp i j sta 表示長為i的字串匹配到j節點且狀態為sta的數量。其中sta儲存的是包含的密碼串情況,在構建fail指標時,當前節點要並上fail指標所指的節點。跑ac自...