洛谷P1357 花園(狀態壓縮 矩陣快速冪)

2021-09-25 18:55:47 字數 1533 閱讀 3719

小l有一座環形花園,沿花園的順時針方向,他把各個花圃編號為1~n(2<=n<=10^15)。他的環形花園每天都會換乙個新花樣,但他的花園都不外乎乙個規則,任意相鄰m(2<=m<=5,m<=n)個花圃中有不超過k(1<=k例如,n=10,m=5,k=3。則

ccpcppppcc 是一種不符合規則的花圃;

ccppppcpcp 是一種符合規則的花圃。

請幫小l求出符合規則的花園種數mod 1000000007

由於請您編寫乙個程式解決此題。

一行,三個數n,m,k。

花園種數mod 1000000007

輸入 #1

10 5 3
輸出 #1

458
輸入 #2

6 2 1
輸出 #2

18
【資料規模】

40%的資料中,n<=20;

60%的資料中,m=2;

80%的資料中,n<=10^5。

100%的資料中,n<=10^15。

假如花園是一條鏈,設f[i][j]為在有i個花圃的情況下,最後m個花圃狀態為j的花園種數。其中j為狀態壓縮下的二進位制數,共有m位,1表示該位為c形花圃。

轉移方程:

ll t1=j>>1,t2=(j>>1)|(1<<(m-1));

if(num_1(t2)<=k)

else

舉個例子,如果m=5,當前狀態為10010,它可能是由狀態01001或11001轉移而來,如果都滿足k的限制的話。

接下來,要考慮到花園是環形的。 

換個角度想,乙個有n個花圃環形花園與乙個有n+m個花圃且前m個花圃與後m個花圃完全相同的鏈狀花園的種類數是一樣的。

假設前m個花圃的狀態為j,那麼我們先將所有f賦值為零,令f[m][j]=1,然後從f[m+1][...]開始計算,最終答案為f[n+m][j]。

列舉所有初始狀態,求和得到最後結果。

由於n的值會很大,但遞推式不複雜,可以採用矩陣快速冪優化演算法。

#include #define ll long long

#define mod 1000000007

using namespace std;

ll n,m,k,len,f[101],y[100];

inline ll num_1(ll st)

return ans;

} struct mat

};mat a,e;

mat mul(mat x,mat y) //矩陣乘

mat pow(mat x,ll y) //矩陣快速冪

return ans;

}mat init()

} }

return pow(a,n);

}int main()

} cout

}

洛谷P1357 花園

給定乙個環形的01序列,保證任意相鄰的m個值中有不超過k個1,求滿足要求的方案數對1e9 7取模的值 狀壓dp 矩陣快速冪 由於m的範圍很小,所以我們考慮狀壓dp儲存狀態,而由於n很大,所以我們考慮矩陣快速冪優化轉移 我們定義 f i,j 表示前i個數最後m個的狀態為j時的方案數,顯然這個dp的初始...

狀壓dp 矩陣 洛谷 P1357 花園

簡單來說,這一題就是乙個狀壓dp用矩陣優化 但是這個矩陣也是最最最基礎的矩陣了 floyd矩陣 dp的話,和第乙個題解hi一樣的 f i s 表示第i位時的方案,s為i i m 1的狀態 然後轉移的時候我們列舉i列舉2個s if v j k f i j f i j f i 1 k mo 這裡的v j...

P1357 花園 矩陣快速冪 DP

題意 乙個只含字母c和p的環形串 求長度為n且每m個連續字元不含有超過k個c的方案數 m 5 n 1e15 題解 用乙個m位二進位制表示狀態 轉移很好想 但是這個題是用矩陣快速冪加速dp的 因為每一位的轉移都是一樣的 用乙個矩陣表示狀態i能否轉移到狀態j 然後跑一遍 統計答案特別講究 因為是乙個環 ...