https://vijos.org/p/1067

守望者-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,否则可能会溢出

分析:快被自己蠢哭了,下午5点开始做这道题一直到现在,9点半。
首先这道题要递推,得出递推式 f[n] = f[n-k] + f[n-k+1] + ...+f[n-1];怎么退出的呢?到n点分为起点从1开始,从2开始...从n-k(一个k就到n点了)开始,从1开始的方案数就是f[n-1],从2开始的就相当于从1到n-1,所以可以写成f[n-2],而从n-k点开始的呢,就直接是f[n-k];
求这个递推式用矩阵来构造举例构造:f[n] = f[n-1] + f[n-2]+f[n-3]
可以写成| 0 1 0 |    | f[n-3] |     | f[n-2] |
           | 0 0 1 | * | f[n-2] | =  | f[n-1] |
           | 1 1 1 |    | f[n-1] |     | f[n-3] + f[n-2] + f[n-1] |
同理原式可以写成 k * K的矩阵,右上角的(k - 1)*(k - 1)主对角线都是一,第k行全为1;
然后就可以写最原始的那个式子了,即:f[1]...f[k],
最后根据n与k的关系分两种情况,k>=n,直接输出,n>k,利用矩阵快速幂求最后的变化矩阵,然后在用他左乘最原始的式子
弱,弱爆了。。。
 #include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std; int n,k;
const int mod = ;
struct Mat
{
__int64 mat[][];
};
Mat operator * (Mat a, Mat b)
{
Mat c;
memset(c.mat, , sizeof(c.mat));
for(int t = ; t <= k; t++)
{
for(int i = ; i <= k; i++)
{
for(int j = ; j <= k; j++)
c.mat[i][j] = ( c.mat[i][j] + a.mat[i][t] % mod * ( b.mat[t][j] % mod ) ) % mod; //就是这里乘法忘了+c.mat[i][j]查了半个小时错,弱爆了
}
}
return c;
}
Mat operator ^ (Mat a, int t)
{
Mat c;
for(int i = ; i <= k; i++)
for(int j = ; j <= k; j++)
c.mat[i][j] = (i == j);
while(t)
{
if(t & )
c = a * c;
a = a * a;
t >>= ;
}
return c;
}
int main()
{
scanf("%d%d", &k,&n);
Mat ori,temp,res;
memset(ori.mat, , sizeof(ori.mat));
for(int i = ; i <= k; i++)
{
for(int j = ; j < i; j++) //这里是处理最原始的那个式子;假设求f[4] ,那么起点可以前3点作为起点,这个好像也能从自己作为起点,所以有个自加,就像f[1] = 1;
{
ori.mat[i][] = (ori.mat[j][] + ori.mat[i][]) % mod;
}
ori.mat[i][]++;
}
if(n <= k)
{
printf("%I64d\n",ori.mat[n][] % mod);
}
else
{
memset(temp.mat, , sizeof(temp.mat));
for(int i = ; i < k; i++)
{
temp.mat[i][i + ] = ;
}
for(int i = ; i <= k; i++)
temp.mat[k][i] = ;
res = temp ^ (n - k);
ori = res * ori;
printf("%I64d\n", ori.mat[k][] % mod);
}
return ;
}

P1067Warcraft III 守望者的烦恼(十大矩阵问题之七求递推式)的更多相关文章

  1. Vijos P1067Warcraft III 守望者的烦恼

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

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

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

  3. vijosP1067Warcraft III 守望者的烦恼

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

  4. C++矩阵加速经典题目:Warcraft III 守望者的烦恼 [vijos 1067]

    Warcraft III 守望者的烦恼 背景 守望者-warden,长期在暗夜精灵的的首都艾萨琳内担任视察监狱的任务,监狱是成长条行的,守望者warden拥有一个技能名叫"闪烁", ...

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

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

  6. vijos Warcraft III 守望者的烦恼

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

  7. HDU5950 Recursive sequence (矩阵快速幂加速递推) (2016ACM/ICPC亚洲赛区沈阳站 Problem C)

    题目链接:传送门 题目: Recursive sequence Time Limit: / MS (Java/Others) Memory Limit: / K (Java/Others) Total ...

  8. HDU5950 Recursive sequence 非线性递推式 矩阵快速幂

    题目传送门 题目描述:给出一个数列的第一项和第二项,计算第n项. 递推式是 f(n)=f(n-1)+2*f(n-2)+n^4. 由于n很大,所以肯定是矩阵快速幂的题目,但是矩阵快速幂只能解决线性的问题 ...

  9. Ipad,IPhone(矩阵求递推项+欧拉定理)

    Ipad,IPhone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...

随机推荐

  1. Install MySQL on Mac OS X——MAC安装MySQL

    很多关于如何安装MySQL的教程已经过时了,或者比必须的步骤复杂得多.这篇教程将展示如何安装MySQL,启动MySQL,以root用户进入MySQL,以及创建删除退出数据库. Step 1: 下载My ...

  2. 【转】【C#】序列化(Serialize)、反序列化(Deserialize)

    序列化又称串行化,是.NET运行时环境用来支持用户定义类型的流化的机制.其目的是以某种存储形成使自定义对象持久化,或者将这种对象从一个地方传输到另一个地方. .NET框架提供了两种串行化的方式: 1. ...

  3. MTK android 工程中如何修改照片详细信息中机型名

    每一个项目的机型名都不相同,因此拍出来的照片需要更改详细信息中的机型名. 那么,具体在哪里修改照片详细信息机型名呢 路径信息:/ALPS.JB3.TDD.MP.V2_TD_xxx/mediatek/c ...

  4. 思科简单教程CCNA

    这是CCNA的内容,从PC配置交换机(或者路由器),这里呢我们使用的软件叫pack 这是ciso开发的一款工具,能生动形象的模拟现实生活中组网技术的过程,下面我大概讲一下流程,想更多的了解我会录制一些 ...

  5. Oracle数据库,数字强制显示2位小数(转)

    Oracle数据库,数字强制显示2位小数 在银行.财务等对数字要求敏感的系统中,数字的显示一般有着严格的要求.今遇到一个需求,如题,要求将数字以两位小数的格式显示,如果没有小数,则强制显示为0.例如: ...

  6. 社交网站好友储存设计和实现(PHP+MySQL)

    最近手头的一个网站新增社交功能,用户可以互加好友. 通常,对好友列表设计是新增一个好友,就往好友列表新增一行,当要查询一个用户好友 SELECT * FROM WHERE userid="1 ...

  7. [matlab]改变矩阵的大小并保存到txt文件

    要完成的任务是,加载一个保存在txt文件中的矩阵, 并把它扩大10倍,并且要再次保存回去 %加载txt文件 >load('Matrix.txt'); %扩大10倍 repmat(Matrix,r ...

  8. 基于win32的socket编程及程序实现

    初步研究了win32平台的Windows Sockets,它是Microsoft Windows的网络程序设计接口,它是从Berkeley Sockets扩展而来的,以动态链接库的形式提供给我们使用. ...

  9. silverlight 双击事件

    silverlight的一些功能真让我感到惊奇 就拿双击事件来说一下 写一个简单的例子 <StackPanel x:Name="st_De" MouseLeftButtonD ...

  10. [转]Extundelete--数据恢复软件

    前言 作为一名运维人员,保证数据的安全是根本职责,所以在维护系统的时候,要慎之又慎,但是有时难免会出现数据被误删除的情况,在这个时候该如何快速.有效地恢复数据显得至关重要,extundelete就是其 ...