把n
nn個無色格仔排成一行,可以把某些格仔染成黑色,但兩個黑色格仔之間必須至少有m
mm個無色格仔,求方案數
首先很明顯
f n=
∑i=0
n−m−
1f
if_n=\sum_^f_i
fn=i=
0∑n−
m−1
fi
然後我們發現∑i=
0n−m
−1fi
\sum_^f_i
∑i=0n−
m−1
fi就是字首和,那我們在矩陣乘法中維護乙個字首和
a =[
∑i=0
n−m−
1fif
n−mf
n−m+
1...
fn−1
fn
]a=\begin\sum_^f_i \\ f_ \\ f_ \\ ... \\ f_ \\ f_ \end
a=⎣⎢⎢⎢
⎢⎢⎢⎡
∑i=
0n−m
−1f
ifn
−mf
n−m+
1..
.fn−
1fn
⎦⎥
⎥⎥⎥⎥
⎥⎤然後看著轉移就好了。
#include
#include
#include
#define ll long long
using
namespace std;
const ll size=
20,xjq=
1e9+7;
struct matrixf;
ll n,m;
matrix operator
*(matrix a,matrix b)
matrix power
(matrix f,ll b)
return ans;
}int
main()
P5004 專心OI 跳房子
傳送門 solution 考慮線性dp。f i 表示前 i 個格仔 僅限於跳到前 i 個格仔 有多少種跳法。則 f i f 1 f 2 f i m 1 不會打xigema,湊合著看吧 然而 n 很大,無法用 operatorname n 的時間來做。發現 m 很小,立刻想到矩陣乘法優化線性dp。維護...
P5004 專心OI 跳房子 解題報告
把 n 個無色格仔排成一行,選若干個格仔染成黑色,要求每個黑色格仔之間至少間隔 m 個格仔,求方案數 根據題面,這一題似乎可以用遞推 設第 i 個格仔的編號為 i 有 i 個格仔時的方案數為 f i 顯然,當 i le m 1 時,可以所有格仔不染色 方案數為 1 種,或者最多有乙個格仔染色 方案數...
P3957 跳房子 單調佇列,dp,二分
這就是之前普及組的第四題 有n個格仔,每個格仔有價值。機械人有固定的跳躍距離d,用k個金幣改進的話,就可以讓跳躍距離在d k到d k之間,不過至少要往前跳1個單位長度,每次都必須跳到格仔上。要求超過需要的價值求需要消耗的最少金幣。二分所需金幣數然後 dp,f i f i 表示跳到第i個格仔最大價值,...