[矩阵十题第七题]vijos 1067 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,否则可能会溢出
来源
杜杜我爱你个人原创
最朴实的dp方程

根据加法原理,把所有可以到达n号监狱的出发点(n-i)的值累加起来。
再看数据范围,O(nk)果断超时,不解释(除非用超算评测或许还可以AC)
总觉得和线性递推长得差不多,于是考虑用矩阵快速幂来优化。首先表示出最初的状态

其中f[0] = 1。接着按照套路来进行矩阵乘法得到下一项

因此我们有

又因为矩阵乘法满足结合律,所以就对那么看起来由0和1构成的矩阵进行快速幂就好了。
Code
/**
* vijos
* Problem#1067
* Accepted
* Time:46ms
* Memory:1016k
*/
#include<iostream>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<cstdlib>
#include<fstream>
#include<sstream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<stack>
using namespace std;
typedef bool boolean;
#define INF 0xfffffff
#define smin(a, b) a = min(a, b)
#define smax(a, b) a = max(a, b)
template<typename T>
inline void readInteger(T& u){
char x;
int aFlag = ;
while(!isdigit((x = getchar())) && x != '-');
if(x == '-'){
x = getchar();
aFlag = -;
}
for(u = x - ''; isdigit((x = getchar())); u = (u << ) + (u << ) + x - '');
ungetc(x, stdin);
u *= aFlag;
} #define moder 7777777 typedef class Matrix {
public:
int* p;
int lines, cols;
Matrix():p(NULL), lines(), cols() { }
Matrix(int lines, int cols):lines(lines), cols(cols) {
p = new int[(lines * cols)];
} int* operator [](int pos) {
return p + pos * cols;
} Matrix operator *(Matrix b) {
if(cols != b.lines) return Matrix();
Matrix res = Matrix(lines, b.cols);
for(int i = ; i < lines; i++) {
for(int j = ; j < b.cols; j++) {
res[i][j] = ;
for(int k = ; k < cols; k++) {
(res[i][j] += ((*this)[i][k] * 1LL * b[k][j]) % moder) %= moder;
}
}
}
return res;
}
}Matrix; template<typename T>
T pow(T a, int pos) {
if(pos == ) return a;
T temp = pow(a, pos / );
if(pos & ) return temp * temp * a;
return temp * temp;
} int k, n;
Matrix unit;
Matrix org; inline void init() {
readInteger(k);
readInteger(n);
} inline void solve() {
org = Matrix(k, );
org[k - ][] = ;
for(int i = k - ; i >= ; i--) {
org[][i] = ;
for(int j = i; j < k; j++)
org[][i] += org[][j];
}
if(n < k) {
printf("%d", org[][n]);
return;
}
unit = Matrix(k, k);
for(int i = ; i < k; i++)
unit[][i] = ;
for(int i = ; i < k; i++)
for(int j = ; j < k; j++)
unit[i][j] = (i == j + ) ? () : ();
Matrix res = pow(unit, n - k + ) * org;
printf("%d", res[][]);
} int main() {
init();
solve();
return ;
}
[矩阵十题第七题]vijos 1067 Warcraft III 守望者的烦恼 -矩阵快速幂的更多相关文章
- vijos 1067 Warcraft III 守望者的烦恼 矩阵
题目链接 我们可以很容易的推出dp的式子, dp[i] = sigma(j : 1 to k) dp[i-j]. 但是n太大了, 没有办法直接算, 所以我们构造一个矩阵, 然后快速幂就好了. 就像这样 ...
- (VIJOS) VOJ 1067 Warcraft III 守望者的烦恼 矩阵快速幂
https://vijos.org/p/1067 就..挺普通的一道题..自己学一下怎么推式子就可以...细节不多但是我还是日常爆细节..比如说循环写成从负数开始... 只求ac不求美观的丑陋 ...
- 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 ...
- C++矩阵加速经典题目:Warcraft III 守望者的烦恼 [vijos 1067]
Warcraft III 守望者的烦恼 背景 守望者-warden,长期在暗夜精灵的的首都艾萨琳内担任视察监狱的任务,监狱是成长条行的,守望者warden拥有一个技能名叫"闪烁", ...
- 矩阵经典题目七:Warcraft III 守望者的烦恼(矩阵加速递推)
https://www.vijos.org/p/1067 非常easy推出递推式f[n] = f[n-1]+f[n-2]+......+f[n-k]. 构造矩阵的方法:构造一个k*k的矩阵.当中右上角 ...
- vijos Warcraft III 守望者的烦恼
题解 转移方程好写吧 一个一维递推式 然后我们可以构造矩阵优化 嗯,最近学一下递推优化 代码 #include<cstdio> #include<cstring> #inclu ...
- [Vijos1067]Warcraft III 守望者的烦恼(DP + 矩阵优化)
传送门 可知 f[i] = f[i - 1] + f[i - 2] + ... + f[i - k] 直接矩阵优化就好了 #include <cstdio> #include <cs ...
- P1067Warcraft III 守望者的烦恼(十大矩阵问题之七求递推式)
https://vijos.org/p/1067 守望者-warden,长期在暗夜精灵的的首都艾萨琳内担任视察监狱的任务,监狱是成长条行的,守望者warden拥有一个技能名叫“闪烁”,这个技能可以把她 ...
- Vijos P1067Warcraft III 守望者的烦恼
题目 背景 守望者-warden,长期在暗夜精灵的的首都艾萨琳内担任视察监狱的任务,监狱是成长条行的,守望者warden拥有一个技能名叫“闪烁”,这个技能可以把她传送到后面的监狱内查看,她比较懒,一般 ...
随机推荐
- 用栈来递归 模板 honoi
用栈来模拟递归的技巧 #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<vector> #include& ...
- 静默方式安装10g数据库软件+升级patch+手工建库
通常我们安装Oracle数据库软件,都是用OUI图形界面来完成的,但有些Unix/Linux系统中并未安装图形系统,也就无法使用图形界面来安装Oracle的产品了,对于这种场景,就只能采用静默方式来安 ...
- 安装中文输入法 ubuntu shortcut desktop
安装中文输入法 Kali自带是不能输入中文的,因此我安装了搜狗输入法和谷歌输入法(我做备份的),安装其一便可以.建议安装前apt-get update下,刷新下.其次安装好任意输入法需要重启下才能正常 ...
- java string.getBytes(“UTF-8”) javascript equivalent
1. byte[] bytes = "test.message".getBytes("UTF-8"); //result: [116, 101, 115, 11 ...
- windows环境下为php打开ssh2扩展
安装步骤 1. 下载 php extension ssh2下载地址 http://windows.php.net/downloads/pecl/releases/ssh2/0.12/ 根据自己PHP的 ...
- 万恶之源 - Python基础数据类型一
整数 整数在Python中的关键字用int来表示; 整型在计算机中运于计算和比较 在32位机器上int的范围是: -2**31-2**31-1,即-2147483648-2147483647 在64 ...
- 万恶之源 - Python基础
Python简介 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆(中文名字:龟叔)为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程 ...
- 飞跃平野(sdut1124)
http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=1124 飞跃原野 Time Limit: 500 ...
- Django-made基础
知识预览 ORM 创建表(建立模型) 添加表记录 查询表记录 修改表记录 删除表记录 回到顶部 ORM 映射关系: 表名 <-------> 类名 字段 <-------> 属 ...
- qt用mingw编译时报错 multiple definition of
网上相关回答不少,但过于简单,这里做一下记录. qt用mingw编译程序时报“multiple definition of …”这个错误,错误信息大概是如下图所示: 1 2 3 首先,检查自己的程序是 ...