zoj3494 ac自動機 數字dp

2022-05-13 17:55:18 字數 1926 閱讀 5899

題解:把給的串建ac自動機,然後得到的bcd[i][j],bcd[i][j]表示在ac自動機上的狀態i,後面加入j會轉移的狀態,-1表示不能加

然後數字dp,dp[i][j]表示取到第i位狀態為j後面的數字隨便取的方案數,這裡是記憶化。

#include#include

#include

#include

#include

#include

#include

#include

#define pb push_back

#define mk make_pair

#define ll long long

#define fi first

#define se second

#define pi 3.14159265

#define ls l,m,rt<<1

#define rs m+1,r,rt<<1|1

#define eps 1e-7

#define pii pair#define pll pairtypedef unsigned

long

long

ull;

const

int mod=1000000009

;const ll inf=0x3f3f3f3f3f3f3f

;const

int n=2e3+100

;using

namespace

std;

char s[300

];int

n;struct

ac_auto

void

init()

intnew_node()

void insert(char *s)

ed[p]=1

; }

void

build()

while(!q.empty())}}

}ac;

int bcd[n][10

];int judge(int x,int

y)

returnx;}

void

slove()

}}ll dp[

210][n];

int bit[300

];ll dfs(

int p,int s,int flag,int z)//

p第幾位,s當前的狀態,flag是否已經有高位小於s,前面是否有非0值

else

int lim=(flag?bit[p]:9

);

for(int i=1;i<=lim;i++)

if(!flag&&!z)dp[p][s]=ans;

return

ans;

}ll

get(char *s)

return dfs(len-1,0,1,1);}

intmain()

ac.build();

slove();

scanf("%s

",s);

int len=strlen(s);

for(int i=len-1;i>=0;i--)

else s[i]='9'

; }

ll ans=0

; ans-=get

(s);

ans%=mod;

scanf("%s

",s);

ans+=get

(s);

ans%=mod;

if(ans<0)ans+=mod;

printf(

"%lld\n

",ans);

}return0;

}/*12 1 2

1 21 1 1

2 1 2

*/

ZOJ 3494 AC自動機 數字DP

有一種bcd編碼方案,求a到b範圍內的數字的bcd編碼有多少個不包含不能包含的字串。數字範圍這麼大,很明顯就能看出來是數字dp。基於ac自動機的數字dp使得數字dp容易了不少,因為ac自動機自帶狀態轉移。在數字dp選取每一位的時候,基於ac自動機狀態轉移一下,如果轉移到不能轉移的狀態,就直接返回 1...

ZOJ 3494 AC自動機 高精度數字DP

題目鏈結 題目大意 給定一些被禁止的bcd碼。問指定範圍內不含有任何這些禁止的bcd碼的數的個數。解題思路 ac自動機部分 首先insert這些被禁止的bcd碼。然後打一下自動機前後狀態的轉移的表,用bcd i j 表示自動機狀態i時,下乙個數字是j的自動機的下乙個狀態。一開始我考慮最先dfs的位在...

zoj3430 AC自動機模擬

jibancanyang author jibancanyang created time 五 5 6 16 14 59 2016 file name jy.cpp problem analyse 此題難就難在編碼,還有題意問的是病毒有多少種不是多少個,注意char已經不能表示解碼之後的字元,要用 ...