BZOJ 4417 Luogu P3990 [SHOI2013]超级跳马 (DP、矩阵乘法)
题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=4417
(luogu)https://www.luogu.org/problemnew/show/P3990
题解: 一看就是矩乘优化dp.
每次跳奇数列?那么我们可以将列两两分组,以两列为一组作为矩阵要记录的状态。一个元素位于组内第一列说明它不可能再跳到这一组的第二列(为了避免算重)。转移矩阵的构造见代码。
那么我们用矩阵来表示转移方程: 设向量\(F[i]\)表示状态,\(A\)表示转移矩阵,\(F[i]=\sum^{i-1}_{j=1}F[j]\times A\)
作差分,\(F[i]-F[i-1]=F[i-1]\times A\), \(F[i]=F[i-1]\times (A+I)\)
注意这个递推式成立的条件是\(i\ge 3\), 即必须预处理出\(F[2]\)的值而不可以通过\(F[1]\)得出(想一想,为什么)。
代码
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cassert>
#include<iostream>
#define llong long long
using namespace std;
inline int read()
{
int x=0; bool f=1; char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
for(; isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+(c^'0');
if(f) return x;
return -x;
}
const int P = 30011;
const int N = 50;
struct Matrix
{
int n;
llong a[(N<<1)+3][(N<<1)+3];
void output() {for(int i=1; i<=n; i++) {for(int j=1; j<=n; j++) printf("%lld ",a[i][j]); puts("");}}
void clear(int _n) {n = _n; for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) a[i][j] = 0ll;}
void unitize() {for(int i=1; i<=n; i++) a[i][i] = 1ll;}
Matrix operator *(const Matrix &arg) const
{
Matrix ret; ret.clear(n);
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
for(int k=1; k<=n; k++)
{
ret.a[i][k] = (ret.a[i][k]+a[i][j]*arg.a[j][k])%P;
}
}
}
return ret;
}
} trans,cur,ans;
int n;
llong m;
void mquickpow(llong y)
{
cur = trans;
for(int i=0; y; i++)
{
if(y&(1ll<<i)) {y-=(1ll<<i); ans = ans*cur;}
cur = cur*cur;
}
}
int main()
{
scanf("%d%lld",&n,&m);
trans.clear(n<<1); cur.clear(n<<1); ans.clear(n<<1);
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
if(j>=i-1 && j<=i+1)
{
trans.a[i][j+n]++;
trans.a[i+n][j]++;
}
}
}
for(int i=1; i<=n+n; i++)
{
for(int j=1; j<=n; j++)
{
for(int k=1; k<=n; k++)
{
if(k>=j-1 && k<=j+1)
{
trans.a[i][k+n] += trans.a[i][j];
}
}
}
}
ans = trans;
for(int i=1; i<=n+n; i++) trans.a[i][i]++;
mquickpow((m-3)>>1);
if(m&1) printf("%lld\n",(ans.a[1][n]+ans.a[n+1][n]+ans.a[n+2][n])%P);
else printf("%lld\n",(ans.a[1][n+n]+ans.a[n+1][n+n]+ans.a[n+2][n+n])%P);
return 0;
}
BZOJ 4417 Luogu P3990 [SHOI2013]超级跳马 (DP、矩阵乘法)的更多相关文章
- Luogu P3990 [SHOI2013]超级跳马
这道题还是一道比较不可做的矩阵题 首先我们先YY一个递推的算法:令f[i][j]表示走到第i行第j列时的方案数,那么有以下转移: f[i][j]=f[i-1][j-2*k+1]+f[i+1][j-2* ...
- 洛谷 P3990 [SHOI2013]超级跳马 解题报告
P3990 [SHOI2013]超级跳马 题目描述 现有一个\(n\) 行 \(m\) 列的棋盘,一只马欲从棋盘的左上角跳到右下角.每一步它向右跳奇数列,且跳到本行或相邻行.跳越期间,马不能离开棋盘. ...
- 【BZOJ 3326】[Scoi2013]数数 数位dp+矩阵乘法优化
挺好的数位dp……先说一下我个人的做法:经过观察,发现这题按照以往的思路从后往前递增,不怎么好推,然后我就大胆猜想,从前往后推,发现很好推啊,维护四个变量,从开始位置到现在有了i个数 f[i]:所有数 ...
- 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 2323】 2323: [ZJOI2011]细胞 (DP+矩阵乘法+快速幂*)
2323: [ZJOI2011]细胞 Description 2222年,人类在银河系外的某颗星球上发现了生命,并且携带了一个细胞回到了地球.经过反复研究,人类已经完全掌握了这类细胞的发展规律: 这种 ...
- 【BZOJ】1009: [HNOI2008]GT考试(dp+矩阵乘法+kmp+神题)
http://www.lydsy.com/JudgeOnline/problem.php?id=1009 好神的题orzzzzzzzzzz 首先我是连递推方程都想不出的人...一直想用组合来搞..看来 ...
- bzoj 4818: [Sdoi2017]序列计数【容斥原理+dp+矩阵乘法】
被空间卡的好惨啊---- 参考:http://blog.csdn.net/coldef/article/details/70305596 容斥,\( ans=ans_{没有限制}-ans{没有质数} ...
- [BZOJ 4417][Shoi2013]超级跳马
4417: [Shoi2013]超级跳马 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 379 Solved: 230[Submit][Status ...
随机推荐
- OSCHINA 公布 2019 年度最受欢迎中国开源软件
https://www.oschina.net/project 此文章从此处转载:https://www.oschina.net/project/top_cn_2019?utm_source=star ...
- Anaconda配置环境变量+创建虚拟环境+pycharm使用虚拟环境
Anaconda配置环境变量+创建虚拟环境 配置环境变量 没有添加系统变量,所有系统根本识别不了conda命令,找不到位置,所以添加以下系统变量: 添加对应Anaconda环境变量:(以自己的安装路径 ...
- HDU1846 Brave Game 题解
题面 本题是一道有向图博弈问题: 该题便是著名的巴什博弈: 我们可以发现,当n=0的时候后手必胜(设其为P态),n=1~m这几种状态由于先手可以一次全部取完导致先手必胜(设其为N态). 接着当n=m+ ...
- POJ 2995 Brackets 区间DP
POJ 2995 Brackets 区间DP 题意 大意:给你一个字符串,询问这个字符串满足要求的有多少,()和[]都是一个匹配.需要注意的是这里的匹配规则. 解题思路 区间DP,开始自己没想到是区间 ...
- C++笔记(0)——判定一个数字是否是素数
博主之前使用的编程语言是Python,但是这门语言的效率比较低(通常,不优化的情况下,但是即便如此我还是偏爱Python),而且博主打算参加PAT考试(真正的原因),及博主打算顺便深入学习下机器学习框 ...
- 20.AutoMapper 之理解你的映射(Understanding Your Mappings)
https://www.jianshu.com/p/4f5c14fbf1c2 理解你的映射(Understanding Your Mappings) AutoMapper 为你的映射创建执行计划.在调 ...
- 定义Vue-router的动态路由,获取传过来的动态参数
设置:在router目录下的index.js文件中,对path属性加上/:id 获取:使用router对象的params.id
- varchar nvarchar 设计长度时 设计成 (2^n)-1 的好处
这个问题想说已久就是博没共享出来 首先提出个问题 CREATE TABLE `test` ( `a` ) DEFAULT NULL, ) ENGINE=InnoDB DEFAULT CHARSET=u ...
- symfony学习笔记——路由
symfony的路由其实就是通过url映射到控制器的一个设置 _test: path: /test/{type}/{page} methods: [GET] defaults: {_con ...
- h5 实现页面上拉加载更多数据
您好,您的上拉加载更多的代码来喽: html:(style部分:html部分:js部分--js部分主要就是监控上拉,调接口) //上拉加载更多css <style> .wait-loadi ...