码迷,mamicode.com
首页 > 其他好文 > 详细

[SHOI 2013]超级跳马

时间:2020-01-30 22:54:12      阅读:62      评论:0      收藏:0      [点我收藏+]

标签:struct   clu   ++   opera   i+1   lin   ons   超级   转移   

Description

题库连接

现有一个 \(n\)\(m\) 列的棋盘,一只马欲从棋盘的左上角跳到右下角。每一步它向右跳奇数列,且跳到本行或相邻行。跳越期间,马不能离开棋盘。试求跳法种数,取模。

\(1\leq n\leq50,2\leq m\leq 10^9\)

Solution

\(f_{i,j}\) 表示在第 \(i\) 列第 \(j\) 行的方案数。那么,\(f_{i,j}=\sum\limits_{k=1}^i\text{odd}(i-k)\cdot(f_{k,j-1}+f_{k,j}+f_{k,j+1})\)

显然如果我们分奇偶做一个前缀和的话就可以 \(O(1)\) 转移。

由于 \(n\) 比较大,并且决策(转移)比较少,那么我们考虑用矩乘法优化。构造 \(1\times n\) 的状态矩阵 \(\mathbf{A_n}\),第 \(1\) 行第 \(i\) 列表示从左上角到 \((n,i)\) 有多少种方法。

显然 \(\mathbf{A_n}[1][1]=1\)。构造状态矩阵 \(\mathbf{S}=\begin{bmatrix}\mathbf{A_n} &\mathbf{A_{n-1}}\end{bmatrix}\)

再构造转移矩阵 \(\mathbf{T}=\begin{bmatrix}\mathbf{V} &\mathbf{I}\\\mathbf{I} &0\end{bmatrix}\)。其中 \(\mathbf V\) 是转移矩阵,用来记录 DP 的转移方程。右上角的单位矩阵是用来累加前缀和到下一个状态矩阵上的。左下角的单位矩阵是将当前的 \(\mathbf{A_n}\) 变成下一个状态矩阵的 \(\mathbf{A_{n-1}}\)

于是矩阵优化即可。注意由于做的是前缀和,所以最后输出时要做一次差分来算出最后一列的方案数。

Code

#include <bits/stdc++.h>
using namespace std;
const int N = 105, yzh = 30011;

int n, m;
struct mat {
    int a[N][N];
    mat () {memset(a, 0, sizeof(a)); }
    mat operator * (const mat &b) const {
        mat ans;
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++)
                for (int k = 1; k <= n; k++)
                    (ans.a[i][j] += a[i][k]*b.a[k][j]%yzh) %= yzh;
        return ans;
    }
} S, T, B;

void qpow(int b) {
    while (b) {
        if (b&1) S = S*T;
        b >>= 1, T = T*T;
    }
}
int main() {
    scanf("%d%d", &n, &m);
    S.a[1][1] = 1;
    for (int i = 1; i <= n; i++)
        T.a[i][i+n] = T.a[i+n][i] = T.a[i][i] = 1;
    for (int i = 1; i < n; i++)
        T.a[i+1][i] = T.a[i][i+1] = 1;
    B = T;  n <<= 1;
    qpow(m-2);
    printf("%d\n", ((S*B).a[1][n>>1]-S.a[1][n]+yzh)%yzh);
    return 0;
}

[SHOI 2013]超级跳马

标签:struct   clu   ++   opera   i+1   lin   ons   超级   转移   

原文地址:https://www.cnblogs.com/NaVi-Awson/p/12244120.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!