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. AlphaGo的前世今生(一)Deep Q Network and Game Search Tree:Road to AI Revolution

    这一个专题将会是有关AlphaGo的前世今生以及其带来的AI革命,总共分成三节.本人水平有限,如有错误还望指正.如需转载,须征得本人同意. Road to AI Revolution(通往AI革命之路 ...

  2. 使用dubbo中间件的zookeeper注册中心时报错

    在项目中搭建soa项目时,使用dubbo服务中间件时需要在虚拟机中创建一个zookeeper注册中心,在配置都没有问题的时候,如果服务端启动成功,但是消费端启动报错并且看不出据地位置时,一定要注意你的 ...

  3. Android studio使用android:style/Theme.Dialog报错:You need to use a Theme.AppCompat theme (or descendant) with this activity. at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)

    查找原因是在activity java代码部分继承了compatactivity public class DialogActivity extends AppCompatActivity 但是在An ...

  4. event.keyCode用法及列表

    HTML 用户名:<input type="text" id="UserAccount" onKeyPress="JumpByEnter(Use ...

  5. flask中缓存cache导入时引发的错误

    安装 pip install flask-cache 初始化 from flask_cache import Cache cache = Cache(config={ 'CACHE_TYPE': 's ...

  6. JDBC 心得

    还记得jdbc的及个步骤, 一是class出对象 2  链接数据库 3 SQL  pre开头的 4 允许SQL,result,exeupdate, 在这里想写的通过反射得到对象, Hibernate有 ...

  7. 一些matlab命令

    expand: R = exprnd(MU) returns an array of random numbers chosen from the exponential distribution w ...

  8. 【redis 学习系列】API的理解与使用(二)

    3.哈希 几乎所有的语言都支持了哈希(hash)类型.在Redis中,哈希类型是指键值本身又是一个键值对结构,形如:value = {{field, value} ... {field, value} ...

  9. TreeView的三种状态,全选,全不选,半选中

    我知道的设置treeview节点的三种状态,如果不是买的控件,那么通过代码,只能设置两种状态,我知道的有三种方法, 第一种是重写treeview,第二种是把三种状态做成小图标,让节点复选框随着不同的状 ...

  10. Mybatis SqlsessionFactory

    在Mybatis 与 Spring 进行整合的时候,我们会进行sqlSessionFactory 的配置,来创建sqlSessionFactory 对象:如下: <bean id="s ...