Warcraft III 守望者的烦恼

背景

守望者-warden,长期在暗夜精灵的的首都艾萨琳内担任视察监狱的任务,监狱是成长条行的,守望者warden拥有一个技能名叫“闪烁”,这个技能可以把她传送到后面的监狱内查看,她比较懒,一般不查看完所有的监狱,只是从入口进入,然后再从出口出来就算完成任务了。

描述

头脑并不发达的warden最近在思考一个问题,她的闪烁技能是可以升级的,k级的闪烁技能最多可以向前移动k个监狱,一共有n个监狱要视察,她从入口进去,一路上有n个监狱,而且不会往回走,当然她并不用每个监狱都视察,但是她最后一定要到第n个监狱里去,因为监狱的出口在那里,但是她并不一定要到第1个监狱。

守望者warden现在想知道,她在拥有k级闪烁技能时视察n个监狱一共有多少种方案?

格式

输入格式

第一行是闪烁技能的等级k(1<=k<=10)

第二行是监狱的个数n(1<=n<=2^31-1)

输出格式

由于方案个数会很多,所以输出它 mod 7777777后的结果就行了

样例1

样例输入1

2

4

样例输出1

5

限制

各个测试点1s

提示

把监狱编号1 2 3 4,闪烁技能为2级,

一共有5种方案

→1→2→3→4

→2→3→4

→2→4

→1→3→4

→1→2→4

小提示:建议用int64,否则可能会溢出

这道题我们可以先考虑k=2的情况,发现其实此题的主要内容就是爬楼梯(k为最多爬多少步,n为有n阶楼梯)。所以在k=2时整个解排出来便是一个裴波那契数列,递推式为\(f_{n}=f_{n-1}+f_{n-2}\)。那么扩展到闪烁步数最大为k的情况,不难发现递推式便为\(f_{n}=f_{n-1}+f_{n-2}+f_{n-3}+...+f_{n-k}\)。

这里有一个初始化的问题让我思考了一段时间,这里阐述一下。如果k是小于n的,那么总的方案数会是多少。不难发现在\(k>n\)时,你最多一次只能爬n步,而不能爬k步,所以在\(k>n\)时,其实方案数就是\(f_{n}\),也就是\(f_{n}=f_{n-1}+f_{n-2}+...+f_{0}\)。

现在来考虑矩阵加速,方法类似于裴波那契数列的构造方法,具体请看此篇博客:https://blog.csdn.net/weixin_44049566/article/details/88946702

这里因为矩阵的阶数随k而定,所以可以使用循环来构造,类似于如下代码:

void pre1(int k) {
n=m=k;
for(int i=1;i<=k-1;i++) c[i+1][i]=1;
for(int i=1;i<=k;i++) c[i][k]=1;
}

加速矩阵构造出来类似于这样:

\(\begin{bmatrix}
& 0 & 0 & ... &0 \\
& 1 & 0& ... & 0\\
& 0 & 1& ... & 0\\
& ... & ... &... & ...\\
& 0 & 0& ... &1
\end{bmatrix}\)*\(\begin{bmatrix}
& f_{1}&f_{2}&...&f_{k}\end{bmatrix}\)

代码

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std; #define N 20
#define LL long long
#define MOD 7777777 LL k,n; struct Matrix {
LL n,m,c[N][N];
Matrix() { memset(c,0,sizeof(c)); };
void _read() {
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%lld",&c[i][j]);
}
Matrix operator * (const Matrix& a) {
Matrix r;
r.n=n;r.m=a.m;
for(int i=1;i<=r.n;i++)
for(int j=1;j<=r.m;j++)
for(int k=1;k<=m;k++)
r.c[i][j]= (r.c[i][j]+ (c[i][k] * a.c[k][j])%MOD)%MOD;
return r;
}
void _print() {
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
if(j!=1) cout<<" ";
cout<<c[i][j];
}
if(i!=n) puts("");
}
}
void pre1(int k) {
n=m=k;
for(int i=1;i<=k-1;i++) c[i+1][i]=1;
for(int i=1;i<=k;i++) c[i][k]=1;
}
void pre2(int k) {
n=1,m=k;
c[1][0]=c[1][1]=1;
for(int i=2;i<=k;i++)
for(int j=i-1;j>=0;j--)
c[1][i]+=c[1][j];
}
Matrix _power(int indexx) {
Matrix tmp,sum;tmp.pre1(k);
for(int i=1;i<=k;i++) sum.c[i][i]=1;sum.m=sum.n=k;
while(indexx>0) {
if(indexx&1) sum=sum*tmp;
tmp=tmp*tmp;
indexx/=2;
}
return sum;
} }A,B; int main() {
cin>>k>>n;
A.pre2(k);
B.pre1(k);
B=B._power(n-k);
A=A*B;
cout<<A.c[1][k];
}

C++矩阵加速经典题目:Warcraft III 守望者的烦恼 [vijos 1067]的更多相关文章

  1. [矩阵十题第七题]vijos 1067 Warcraft III 守望者的烦恼 -矩阵快速幂

    背景 守望者-warden,长期在暗夜精灵的的首都艾萨琳内担任视察监狱的任务,监狱是成长条行的,守望者warden拥有一个技能名叫“闪烁”,这个技能可以把她传送到后面的监狱内查看,她比较懒,一般不查看 ...

  2. 矩阵经典题目七:Warcraft III 守望者的烦恼(矩阵加速递推)

    https://www.vijos.org/p/1067 非常easy推出递推式f[n] = f[n-1]+f[n-2]+......+f[n-k]. 构造矩阵的方法:构造一个k*k的矩阵.当中右上角 ...

  3. vijos 1067 Warcraft III 守望者的烦恼 矩阵

    题目链接 我们可以很容易的推出dp的式子, dp[i] = sigma(j : 1 to k) dp[i-j]. 但是n太大了, 没有办法直接算, 所以我们构造一个矩阵, 然后快速幂就好了. 就像这样 ...

  4. VOJ 1067 Warcraft III 守望者的烦恼 (矩阵高速功率+dp)

    主题链接 明显的 dp[n] = dp[n-k] + dp[n-k+1] + ... +dp[n-1]; 然后要用矩阵来优化后面的状态转移. 也就是矩阵 0 1 0 0    a     b 0 0 ...

  5. [Vijos1067]Warcraft III 守望者的烦恼(DP + 矩阵优化)

    传送门 可知 f[i] = f[i - 1] + f[i - 2] + ... + f[i - k] 直接矩阵优化就好了 #include <cstdio> #include <cs ...

  6. (VIJOS) VOJ 1067 Warcraft III 守望者的烦恼 矩阵快速幂

    https://vijos.org/p/1067   就..挺普通的一道题..自己学一下怎么推式子就可以...细节不多但是我还是日常爆细节..比如说循环写成从负数开始...   只求ac不求美观的丑陋 ...

  7. vijos Warcraft III 守望者的烦恼

    题解 转移方程好写吧 一个一维递推式 然后我们可以构造矩阵优化 嗯,最近学一下递推优化 代码 #include<cstdio> #include<cstring> #inclu ...

  8. [vijos1067]Warcraft III 守望者的烦恼

    就是上次考得fyfy.竟然是原题... // It is made by XZZ #include<cstdio> #include<algorithm> #include&l ...

  9. vijosP1067Warcraft III 守望者的烦恼

    vijosP1067Warcraft III 守望者的烦恼 链接:https://vijos.org/p/1067 [思路] 矩阵乘法. 可以得出递推式:      f[i]=sum{ f[n-1], ...

随机推荐

  1. mysql查询正在执行的sql

    mysql> SHOW VARIABLES LIKE "general_log%"; +------------------+------------------------ ...

  2. UVa514 Rails (栈)

    题意:一列有n节车厢的火车按顺序进站,给你一个出站顺序,问你该火车的车厢能否以该顺序出站? 分析:出站的车厢满足后进先出的关系,所以我们考虑采用栈s 假设车厢一共有n节,n = 5: 进站顺序A:1 ...

  3. Idea实用快捷键

    快速找到最近使用的文件的设置       ctrl+E    general 里设置 自动补全末尾的字符                Ctrl+Shift+Enter 选择当前光标位置单词      ...

  4. git clone失败

    操作: $ git clone https://github.com/zjun615/DragListView.gitCloning into 'DragListView'...fatal: unab ...

  5. Android辅助开发工具合集

    https://github.com/389273716/android-skill-summary/blob/master/开发工具使用指南/辅助开发工具.md

  6. Scrapy中集成selenium

    面对众多动态网站比如说淘宝等,一般情况下用selenium最好 那么如何集成selenium到scrapy中呢? 因为每一次request的请求都要经过中间件,所以写在中间件中最为合适 from se ...

  7. mybatis generator 源码学习

    mybatis/generator 源码地址mybatis/parent 源码地址1. 分别点击Download ZIP下载到本地. 2. 解压generator-master.zip中的core到g ...

  8. Swift UITableView嵌套UICollectionView点击事件冲突(点击事件穿透)

    不管是啥都响应tableviewcell class JYShopCertificationCell: UITableViewCell { override func hitTest(_ point: ...

  9. 安装使用aria2下载百度网盘内容(转)

    原文地址:https://blog.csdn.net/wudi1107/article/details/80728891 安装使用aria2下载百度网盘内容 目前在Linux中没有好用的百度网盘客户端 ...

  10. HTML导出Excel文件(兼容IE及所有浏览器)

    注意:IE浏览器需要以下设置: 打开IE,在常用工具栏中选择“工具”--->Internet选项---->选择"安全"标签页--->选择"自定义级别&q ...