SHOI2013 超級跳馬

2022-02-08 23:05:30 字數 1188 閱讀 8485

我是常年遊蕩於題解區的幽靈。

直觀的想法就是字首和+差分優化dp, 但還有些比較奇妙的方法or trick:

\(f[i][j] = f[i-1][j-1]+f[i-1][j]+f[i-1][j+1]+\color\), 因為可以一步跳到 \(f[i][j]\) 的狀態也可以一步跳到 \(f[i-2][j]\), 反過來也成立 。

只考慮從左邊某個特定的列的轉移矩陣, 設為 \(j\), 設第 \(i\) 列的答案矩陣是 \(a_i\), 則有:\(a_n = j*(a_+a_+a_+\cdots)\) 且 \(a_ = j*(a_+a_+a_+\cdots)\), 不難得出 \(a_n = j*a_+a_\), 這也是個遞推, 構造矩陣:

\[[ \begin

j & e\\

e & o

\end

] *[ \begin

a_n\\

a_ \end

]=[\begin

a_\\

a_ \end

]\]其中 \(e\) 是單位矩陣而 \(o\) 是全零矩陣,就可以大力遞推了。

這個, 建圖

接下來選擇性地實現/口胡上述的某些解法(我挺中意矩陣套矩陣的解法)

目錄s0[i]維護與當前列差偶數列的第i行的方案數之和,s1[i]則是相差奇數列的。

s1[i] <- s0[i]

#includeusing namespace std;

const int mo = 30011;

int n,m;

int qm(int x)

struct m

};m operator*(const m &a, const m &b)

m operator+(const m &a, const m &b)

struct m2 s,t,delta;

m2 operator*(const m2 &a, const m2 &b)

int main()

m -= 3;

delta = t;

while(m)

s = delta*s;

printf("%d",s.t[1][1].t[n][1]);

return 0;

}

矩陣乘 Shoi2013 超級跳馬

問題 f shoi2013 超級跳馬 時間限制 1 sec 記憶體限制 256 mb 題目描述 現有乙個n行m列的棋盤,乙隻馬欲從棋盤的左上角跳到右下角。每一步它向右跳奇數列,且跳到本行或相鄰行。跳越期間,馬不能離開棋盤。例如,當n 3,m 10時,下圖是一種可行的跳法。試求跳法種數mod 3001...

bzoj 4417 Shoi2013 超級跳馬

題意 現有乙個n行m列的棋盤,乙隻馬欲從棋盤的左上角跳到右下角。每一步它向右跳奇數列,且跳到本行或相鄰行。試求跳法種數mod 30011。題解 dp 矩陣乘法 快速冪 設f i j 表示走到第2i 1列,第 j 行的方案數,g i j 表示走到第2i 列,第j行的方案數。那麼f i j k 1i 1...

SHOI2013 扇形面積並

補一張圖 我們嘗試把圓上的扇形轉化成直線上的矩形 我們維護 1,2m 的區間,那麼每個能產生貢獻的子區間的長度第k大的半徑的平方的總和就是answer了。怎麼轉化呢?左端點為a1 m 1,右端點為a2 m。為什麼要 m?因為原先的範圍是 m,m 的,所以整體右移。為什麼左端點要 1?因為我們維護的是...