Luogu P3990 [SHOI2013]超级跳马
这道题还是一道比较不可做的矩阵题
首先我们先YY一个递推的算法:令f[i][j]表示走到第i行第j列时的方案数,那么有以下转移:
f[i][j]=f[i-1][j-2*k+1]+f[i+1][j-2*k+1]+f[i][j-2*k+1](1<=k<=i/2)
但这样是很慢的,然后我们就可以前缀和优化
这里有两种方法,一个是用奇偶数行进行讨论,还有一种我认为是比较清晰的也比较容易理解
我们先来看一张图:

我们令f[i][j]表示前面可以转移到它的前缀和。例如图中的蓝色格子就是前6个格子的和
然后我们发现红色格子就是由蓝色格子+与它相近(i坐标差值为1)的3个黄色格子的值
然后就可以O(nm)求,但是这显然是过不了的
但是我们仔细研究一下发现每一次的转移都是等价的,所以我们用矩阵优化
由于每一列的值都和它前面两列有关,所以我们需要一个2*n*2*n的矩阵来转移,这个的话大概长这样(n=3时)

具体还是看CODE吧,然后就是常规的矩阵快速幂了
CODE
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long LL;
const int N=55,mod=30011;
int n,m;
struct Matrix
{
int n,m;
LL a[N<<1][N<<1];
inline void Dt_init(void)
{
register int i; memset(a,0,sizeof(a)); n>>=1;
for (i=1;i<=n;++i)
a[i][i+n]=a[i+n][i]=1;
for (i=1;i<=n;++i)
{
if (i^1) a[i][i-1]=1;
if (i^n) a[i][i+1]=1;
a[i][i]=1;
} n<<=1;
}
inline void cri_init(void)
{
register int i; memset(a,0,sizeof(a));
for (i=1;i<=n;++i)
a[i][i]=1;
}
};
inline Matrix mul(Matrix A,Matrix B)
{
Matrix C; C.n=A.n; C.m=B.m; memset(C.a,0,sizeof(C.a));
for (register int i=1;i<=C.n;++i)
for (register int j=1;j<=C.m;++j)
for (register int k=1;k<=A.m;++k)
C.a[i][j]=(C.a[i][j]+A.a[i][k]*B.a[k][j])%mod;
return C;
}
inline Matrix quick_pow(Matrix A,int p)
{
Matrix T; T.n=T.m=A.n; T.cri_init();
while (p)
{
if (p&1) T=mul(T,A);
A=mul(A,A); p>>=1;
}
return T;
}
int main()
{
scanf("%d%d",&n,&m);
Matrix A; A.n=A.m=n<<1; A.Dt_init();
A=quick_pow(A,m-2);
printf("%lld",(A.a[n][1]+A.a[n-1][1])%mod);
return 0;
}
Luogu P3990 [SHOI2013]超级跳马的更多相关文章
- BZOJ 4417 Luogu P3990 [SHOI2013]超级跳马 (DP、矩阵乘法)
题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=4417 (luogu)https://www.luogu.org/prob ...
- 洛谷 P3990 [SHOI2013]超级跳马 解题报告
P3990 [SHOI2013]超级跳马 题目描述 现有一个\(n\) 行 \(m\) 列的棋盘,一只马欲从棋盘的左上角跳到右下角.每一步它向右跳奇数列,且跳到本行或相邻行.跳越期间,马不能离开棋盘. ...
- P3990 [SHOI2013]超级跳马
传送门 首先不难设\(f[i][j]\)表示跳到\((i,j)\)的方案数,那么不难得到如下转移 \[f[i][j]=\sum\limits_{k=1}^{\frac n2}f[i-2k+1][j-1 ...
- [bzoj4417] [洛谷P3990] [Shoi2013] 超级跳马
Description 现有一个n行m列的棋盘,一只马欲从棋盘的左上角跳到右下角.每一步它向右跳奇数列,且跳到本行或相邻行.跳越期间,马不能离开棋盘.例如,当n = 3, m = 10时,下图是一种可 ...
- [BZOJ 4417][Shoi2013]超级跳马
4417: [Shoi2013]超级跳马 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 379 Solved: 230[Submit][Status ...
- [题解][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$同奇偶性的转移和奇偶 ...
- 【bzoj4417】[Shoi2013]超级跳马 矩阵乘法
题目描述 现有一个n行m列的棋盘,一只马欲从棋盘的左上角跳到右下角.每一步它向右跳奇数列,且跳到本行或相邻行.跳越期间,马不能离开棋盘.例如,当n = 3, m = 10时,下图是一种可行的跳法. ...
随机推荐
- Flutter 不一样的跨平台解决方案
本文主要介绍Flutter相关的东西,包括Fuchsia.Dart.Flutter特性.安装以及整体架构等内容. 1. 简介 Flutter作为谷歌最近推出的跨平台开发框架,一经推出便吸引了不少注意. ...
- (后端)java回调机制
转自强哥: 所谓回调,就是客户程序C调用服务程序S中的某个函数A,然后S又在某个时候反过来调用C中的某个函数B,对于C来说,这个B便叫做回调函数.例如Win32下的窗口过程函数就是一个典型的回调函数. ...
- python包中__init__.py的作用
1.__init__.py定义包的属性和方法 一般为空文件,但是必须存在,没有__init__.py表明他所在的目录只是目录不是包 2.导入包的时候使用 例如有一个test目录,test下有xx1.p ...
- CSS| 學習心得
resize :both , 只有overflow設置為auto時, 才能起作用???
- EntityFramework Code-First 简易教程(八)-------一对一
配置一对一(One-to-One)关系: 两个实体中,如果一个实体的一个实例与另一个实体相关,则我们就叫做一对一关系 查看如下代码: public class Student { public Stu ...
- idea 修改单个文件的 编码格式
- 【PAT】B1074 宇宙无敌加法器(20 分)
打一开始做就听人说这个难,吓得我把它放到了最后做,不过如此嘛. 这里说说样例的坑点 1.最后结果可能高位有0:例如样例结果07201 2.结果会进位, 3.有可能结果是0,(此处取决于你的输出方式) ...
- 12个HTML和CSS必须知道的重点难点问题
这12个问题,基本上就是HTML和CSS基础中的重点个难点了,也是必须要弄清楚的基本问题,其中定位的绝对定位和相对定位到底相对什么定位?这个还是容易被忽视的,浮动也是一个大坑,有很多细节.这12个知识 ...
- 配置私有SSH
1.cd ~/.ssh进入ssh文件夹. 2.ls,查看文件夹里面的内容 3.ssh-keygen -t rsa -C "zhanggui@marchsoft.cn” 一路回车 4.cd ~ ...
- 关于plist文件的那些事
今天遇到新生问一个问题,就是用自己定义了一个plist文件,然后可以往里面写东西,但是写过再次运行的时候里面的数据总是最后一次写入的数据.后来就专门研究了一下plist文件. 大家都知道当你创建一个项 ...