[SHOI2013]超级跳马
题目描述
现有一个n 行m 列的棋盘,一只马欲从棋盘的左上角跳到右下角。每一步它向右跳奇数列,且跳到本行或相邻行。跳越期间,马不能离开棋盘。试求跳法种数mod 30011。
输入输出格式
输入格式:
仅有一行,包含两个正整数n, m,表示棋盘的规模。
输出格式:
仅有一行,包含一个整数,即跳法种数mod 30011。
输入输出样例
输入样例#1:
3 5
输出样例#1:
10
说明
对于10%的数据,1 ≤ n ≤ 10,2 ≤ m ≤ 10;
对于50%的数据,1 ≤ n ≤ 10,2 ≤ m ≤ 10^5;
对于80%的数据,1 ≤ n ≤ 10,2 ≤ m ≤ 10^9;
对于100%的数据,1 ≤ n ≤ 50,2 ≤ m ≤ 10^9。
题解
好久没写矩乘有点忘了
但是这种不难的题还是可以写出来的==
DP式子显然\(f[i][j] = (Sum[i-1][j]+Sum[i-1][j-1]+Sum[i-1][j+1])\)
那个\(Sum[i][j]\)表示的是第j行前i列的前缀和
然后这样不好做矩乘
可以用\(f[i][j]\)表示第j行前i列的前缀和
然后就是\(f[i][j] = f[i-2][j] + f[i-1][j] + f[i-1][j-1] + f[i-1][j+1]\)
但是这是个前缀和
所以\(Ans=f[m-1][n]+f[m-1][n-1]\)
这样就可以矩乘了
构造一个\((1 , n*2)\)的初始矩阵
前n个表示的是当前列的每一行的\(f[][]\)
后n个表示的是当前列的上一列的每一行的\(f[][]\)
然后转移矩阵就肥肠简单了
只需要把要转移的位置补上1就可以了
代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
const int N = 105 ;
const int mod = 30011 ;
using namespace std ;
int n , m , E ;
int t[N][N] , Ans ;
struct Matrix {
int f[N][N] ;
inline Matrix () { memset(f , 0 , sizeof(f)) ; }
inline void Start() { for(int i = 1 ; i <= E ; i ++) f[i][i] = 1 ; }
inline friend Matrix operator * (Matrix a , Matrix b) {
Matrix temp ;
for(int i = 1 ; i <= E ; i ++)
for(int j = 1 ; j <= E ; j ++)
for(int k = 1 ; k <= E ; k ++)
temp.f[i][j] = (temp.f[i][j] + a.f[i][k] * b.f[k][j]) % mod ;
return temp ;
}
} st , b , Now ;
inline Matrix Fpw(Matrix Base , int k) {
Matrix temp ; temp.Start() ;
while(k) {
if(k & 1) temp = temp * Base ;
Base = Base * Base ; k >>= 1 ;
}
return temp ;
}
int main() {
cin >> n >> m ; t[1][1] = 1 ; E = (n << 1) ;
for(int i = 1 ; i <= n ; i ++) t[2][i] = (t[1][i] + t[1][i - 1] + t[1][i + 1]) % mod ;
if(m <= 3) { Ans = (t[m - 1][n] + t[m - 1][n - 1]) % mod ; printf("%d\n",Ans) ; return 0 ; }
for(int i = 1 ; i <= n ; i ++) st.f[1][i] = t[2][i] ;
for(int i = n + 1 ; i <= E ; i ++) st.f[1][i] = t[1][i - n] ;
for(int i = 1 ; i <= n ; i ++) {
b.f[i][i] = 1 ;
if(i != 1) b.f[i - 1][i] = 1 ;
if(i != n) b.f[i + 1][i] = 1 ;
b.f[i + n][i] = 1 ;
}
for(int i = n + 1 ; i <= E ; i ++) b.f[i - n][i] = 1 ;
Now = Fpw(b , m - 3) ; st = st * Now ;
Ans = (st.f[1][n] + st.f[1][n - 1]) % mod ;
cout << Ans << endl ;
return 0 ;
}
[SHOI2013]超级跳马的更多相关文章
- [BZOJ 4417][Shoi2013]超级跳马
4417: [Shoi2013]超级跳马 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 379 Solved: 230[Submit][Status ...
- 洛谷 P3990 [SHOI2013]超级跳马 解题报告
P3990 [SHOI2013]超级跳马 题目描述 现有一个\(n\) 行 \(m\) 列的棋盘,一只马欲从棋盘的左上角跳到右下角.每一步它向右跳奇数列,且跳到本行或相邻行.跳越期间,马不能离开棋盘. ...
- [题解][SHOI2013]超级跳马 动态规划/递推式/矩阵快速幂优化
这道题... 让我见识了纪中的强大 这道题是来纪中第二天(7.2)做的,这么晚写题解是因为 我去学矩阵乘法啦啦啦啦啦对矩阵乘法一窍不通的童鞋戳链接啦 层层递推会TLE,正解矩阵快速幂 首先题意就是给你 ...
- BZOJ4417: [Shoi2013]超级跳马
Description 现有一个n行m列的棋盘,一只马欲从棋盘的左上角跳到右下角.每一步它向右跳奇数列,且跳到本行或相邻行.跳越期间,马不能离开棋盘.例如,当n = 3, m = 10时,下图是一种可 ...
- 【BZOJ4417】: [Shoi2013]超级跳马
题目链接: 传送. 题解: 矩阵快速幂优化DP. 先考虑$nm^2$DP,设$f_{(i,j)}$表示从$1,1$到$i,j$的方案,显然这个方程和奇偶性有关,我们考虑某列的$i$同奇偶性的转移和奇偶 ...
- Luogu P3990 [SHOI2013]超级跳马
这道题还是一道比较不可做的矩阵题 首先我们先YY一个递推的算法:令f[i][j]表示走到第i行第j列时的方案数,那么有以下转移: f[i][j]=f[i-1][j-2*k+1]+f[i+1][j-2* ...
- 【bzoj4417】[Shoi2013]超级跳马 矩阵乘法
题目描述 现有一个n行m列的棋盘,一只马欲从棋盘的左上角跳到右下角.每一步它向右跳奇数列,且跳到本行或相邻行.跳越期间,马不能离开棋盘.例如,当n = 3, m = 10时,下图是一种可行的跳法. ...
- P3990 [SHOI2013]超级跳马
传送门 首先不难设\(f[i][j]\)表示跳到\((i,j)\)的方案数,那么不难得到如下转移 \[f[i][j]=\sum\limits_{k=1}^{\frac n2}f[i-2k+1][j-1 ...
- BZOJ 4417 Luogu P3990 [SHOI2013]超级跳马 (DP、矩阵乘法)
题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=4417 (luogu)https://www.luogu.org/prob ...
随机推荐
- 2k进制数(codevs 1157)
题目描述 Description 设r是个2k进制数,并满足以下条件: (1)r至少是个2位的2k进制数. (2)作为2k进制数,除最后一位外,r的每一位严格小于它右边相邻的那一位. (3)将r转换为 ...
- KMP算法 C#实现 字符串查找简单实现
KMP算法 的C#实现,初级版本 static void Main(string[] args) { #region 随机字符 StringBuilder sb = new StringBuilder ...
- Letter Combinations of a Phone Number(带for循环的DFS,组合问题,递归总结)
Given a digit string, return all possible letter combinations that the number could represent. A map ...
- Django学习系列之模板系统
一.模板标签 if/else {% if %}标签检查一个变量的值是否为真或者等于另外一个值,如果为真,系统会执行{% if %}和{% endif %}之间的代码块,例如: {% if ...
- node安装-Win+Linux+Mac osx
node下载地址,除了Mac osx或Win平台,仅有Linux平台命令安装. Win.Mac 点击即可下载(注:Mac有dmg和pkg安装格式). Linux分为Redhot和Deepin系列,安装 ...
- javascript返回顶端源代码
<div style="display:none" id="goTopBtn"><img src="http://www.unity ...
- Python中flatten用法
Python中flatten用法 原创 2014年04月16日 10:20:02 标签: Python / flatten 22667 一.用在数组 >>> a = [[1,3],[ ...
- 复制class文件到as中出现非法字符,须要class,interface货enum
问题如题,出现此情况是在导入eclipse项目到Android Studio出现这种错误, 非法字符: '\ufeff' 解决方式|错误: 须要class, interface或enum,查阅后了解到 ...
- xode5.1.1设置IOS欢迎界面的方法
先准备3张不同尺寸的欢迎图.文件名称分别为: Default.png iPhone 320X480分辨率屏幕默认启动图片. Default@2x.png iPhone 640X960分辨率屏幕默认启 ...
- debug 和release 的区别
http://blog.csdn.net/h_wlyfw/article/details/26688677