「<<」 的運算優先順序低於 『+』!!!
貌似對矩陣理解更深刻了!
2<=m<=5,相鄰的m個花圃可能有2^m種狀態 ,用0~2^m-1來表示
要求有不超過k個c形花圃,對應其二進位制形式中的0不超過k個。
標記出0~2^m-1中滿足條件的狀態x,
對於每個狀態x,前m個花圃會出現1次
f(i,x)表示前i個花圃中,最後m個花圃的狀態是x的方案數。
例:n=6,m=2,k=1
x取01,10,11
f(2,01)增加1個花圃,可以得到狀態f(3,10)和f(3,11)
f(2,10)增加1個花圃,可以得到狀態f(3,01)
f(2,11)增加1個花圃,可以得到狀態f(3,10)和f(3,11)
花圃圍成一圈,要使任意相鄰的m個都滿足要求,
對於每個狀態x,由f(m,x)出發,求f(n+m,x)即可
再累加求得結果。
狀態x增加1位後可能產生的狀態:
x%2^(m-1)2, x%2^(m-1)2+1
複雜度:o(n)
40%的資料中,n<=20;
60%的資料中,m=2;
80%的資料中,n<=10^5。
100%的資料中,n<=10^15。 會超時。
加速優化:
考慮狀態x從何而來?
x/2 和 x/2+2^(m-1)
例:m=5,k=3,狀態00111 可以由 00011 和 10011 再加乙個1得到。
用矩陣乘法來實現:
n=6,m=2,k=1,
(1 1 0 0)
(f(m,00) f(m,01) f(m,10) f(m,11)) * (0 0 1 1)
(1 1 0 0)
(0 0 1 1)
利用矩陣乘法快速冪優化加速。
#include #include #define mo 1000000007
#define ll long long
ll n,m,k,n;
ll a[40][40],b[40][40],tmp[40][40];
int can[40];
inline void f(ll fo[40],ll to[40])
int main()
if(cnt<=k)
b[i][i]=1;
}while(n!=1)
f(a,b);
ll ans=0;
for(int i=0;i<=n;i++)
if(can[i])
ans+=b[i][i],ans%=mo;
printf("%d\n",ans);
return 0;
}
洛谷 1357 花園
的運算優先順序低於 貌似對矩陣理解更深刻了!2 m 5,相鄰的m個花圃可能有2 m種狀態 用0 2 m 1來表示 要求有不超過k個c形花圃,對應其二進位制形式中的0不超過k個。標記出0 2 m 1中滿足條件的狀態x,對於每個狀態x,前m個花圃會出現1次 f i,x 表示前i個花圃中,最後m個花圃的狀...
洛谷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...