bzoj1009 GT考試 dp 矩陣快速冪

2021-07-10 08:37:42 字數 1225 閱讀 7398

題意:構造乙個字串(數字0-9)不含乙個子串的個數

我這麼蒟蒻腫麼可能想到是dp嘛~~~

定義f[i][j]表示當前構造了i位,與模式串p匹配了前j位的方案數

然後列舉下一位填什麼,然後乘上當前構造出來的和模式串匹配到k的方案數。

即是f[i+1][k]+=f[i][j]*a[j][k].(因為從j轉移到k,可以用的數字不一定只有乙個)

這裡a[j][k]表示當前和p匹配到j,再加一位和p匹配到k的方案數

觀察一下,這個式子滿足矩陣的性質,於是就可以用矩陣來做。

終點是構造a(矩陣大小不超過20*20)

可以這麼搞

對於1-m的這麼長的式子,假設當前處理到第j位,然後列舉下乙個數字是什麼,看能轉到哪乙個k,就把轉移矩陣a[j][k]+1.

這種搞法的正確性一開始我非常的不理解,用了好長時間才弄明白。

我們可以這麼看,把它想象成已經處理好next陣列的p串,和文字串s(假想)來匹配

假設已經匹配到前j位,然後j+1位就會出現要麼相同,要麼不同,不同的話就相當於乙個s和p匹配失配,j就會轉到next[j](k),轉後就把這個轉移路徑+1.

構造的時候把j當成i而已,思路大致是:   假設前i位匹配成功,再加一位(列舉),然後當成乙個新串s和p匹配,如果匹配了前k位,就把a[j][k]+1.

好多題解沒有講這個矩陣的構造原理,我也是花了好長時間閱讀翻譯**的- -

真是蒟蒻啊~~~~~~~~~~~~~~~~~~~~~~

附上**:

#include#include#include#include#include#include#includeusing namespace std;

int n,m,m;

/**/

int next[25];

char p[25];

struct mat

};mat operator *(mat a,mat b)

return c;

}int main()

mat t;

for(int i=0;i0&&p[t+1]-'0'!=j)t=next[t];

if(p[t+1]-'0'==j)t++;

if(t!=m)t.mat[i][t]=(t.mat[i][t]+1)%m;}}

mat s;

s=t^n;

int ans=0;

for(int i=0;i

BZOJ 1009 GT考試(dp 矩陣快速冪)

description 阿申準備報名參加gt g t考試,准考證號為 n n 位數x1 x2.xn 0 x i 9 role presentation style position relative x1x 2.xn 0 x i 9 x1x2.xn 0 x i 9 他不希望准考證號上出現不吉利的數字...

BZOJ 1009 GT考試 KMP 矩陣快速冪

題意 b為非法數字b 1 b m 其位數 20.某個數有n位,每位可以填入 0,9 n 1e9 問有多少種填數字方案,滿足n位中沒有非法數字m出現?先不考慮n範圍 則可以設定dp i j 表示放了合法放了前i位,其字尾j和非法的前j位相同的方法數.轉移狀態顯然是一位一位新增 顯然dp i 1 j 1...

bzoj1009矩陣快速面 kmp

其實kmp真的很次要,求長度為20的kmp感覺真的有點殺雞用牛刀 這題思路相當明確 一看題就是數字dp,一看n的大小就是矩陣 矩陣的構造用m m比較方便,本來想寫1 m的矩陣乘m m的,但是感覺想起來太麻煩就偷懶,沒想到1a了 log的速度的確可以,87ms賊快,好久沒見這麼短的執行時間了 1 in...