Vijos 1067Warcraft 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,否则可能会溢出

来源

杜杜我爱你个人原创

pre.cjk { font-family: "Droid Sans Fallback", monospace }
p { margin-bottom: 0.25cm; line-height: 120% }

注意矩阵的对应项之间的关系,初始化,以及开long
long 
 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<cmath>
 7 #include<ctime>
 8 #include<queue>
 9 #include<stack>
10 #include<map>
11 #include<set>
12 #define ll long long
13 #define mod 7777777
14 #define re register
15 using namespace std;
16 ll c[2][11][11];
17 ll s[11][11];
18 int n,k;
19 inline void init( ) {
20   for(re int i=1;i<k;i++) c[1][i+1][i]=1;
21   for(re int i=1;i<=k;i++) c[1][i][k]=1;
22   c[0][1][k]=1;
23 }
24 inline void count(int a , int b) {
25   for(re int i=1;i<=k;i++)
26     for(re int j=1;j<=k;j++)
27       for(re int u=1;u<=k;u++)
28     s[i][j]=(s[i][j]+c[a][i][u]*c[b][u][j])%mod;
29   for(re int i=1;i<=k;i++)
30     for(re int j=1;j<=k;j++)
31       c[a][i][j]=s[i][j],s[i][j]=0;
32   return;
33 }
34 int main( )
35 {
36   freopen("qyp.in","r",stdin);
37   freopen("qyp.out","w",stdout);
38   cin>>k>>n;
39   init();
40   while(n){
41     if(n&1) count(0,1);
42     n>>=1;
43     count(1,1);
44   }
45   printf("%lld",c[0][1][k]);
46   return 0;
47 }
时间: 2024-08-24 17:46:14

Vijos 1067Warcraft III 守望者的烦恼的相关文章

矩阵十题【七】vijos 1067 Warcraft III 守望者的烦恼

题目链接:https://vijos.org/p/1067 题目大意:给你一个k以及n,k代表最多走的步数,n代表一共要走的步数. 问一共有多少种方法,结果mod7777777 题目意思是很明了,具体的公式也能推出来 状态转移方程为:f[n]=f[n-1]+f[n-2]+....f[n-k]. f[0]=1 当k=1,   f[1]=1; f[2]=f[1]=1; f[3]=f[2]=1; f[4]=f[3]=1; 当k=2,   f[1]=1; f[2]=f[1]+f[0]=2; f[3]=f

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

https://www.vijos.org/p/1067 很容易推出递推式f[n] = f[n-1]+f[n-2]+......+f[n-k]. 构造矩阵的方法:构造一个k*k的矩阵,其中右上角的(k-1)*(k-1)的矩阵是单位矩阵,第k行的每个数分别对应f[n-1],f[n-2],,f[n-k]的系数.然后构造一个k*1的矩阵,它的第i行代表f[i],是经过直接递推得到的.设ans[][]是第一个矩阵的n-k次幂乘上第二个矩阵,f[n]就是ans[k][1]. 注意:用__int64 #in

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 1 0 * b =  c 0 0 0 1    c     d 1 1 1 1    d    a+b+c+d 然后跑快速幂 #include <iostream> #include <cstdio> #include <algorithm> #include <c

vijosP1067Warcraft III 守望者的烦恼

链接:https://vijos.org/p/1067 [思路] 矩阵乘法. 可以得出递推式:      f[i]=sum{ f[n-1],f[n-2]…f[n-k] }   矩阵乘法加速转移如下: 1.   原始矩阵F  1 x k: |  1,0,0,0,0,…| 2.   转移矩阵T  k x k: | 1 , 0,  …  | | 1, 1 ,  …  | | 1, 0, 1,0  | | 1 0, 0, 1  | 即有如下转移: (上图转移矩阵有错) [代码] 1 #include<c

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

传送门 可知 f[i] = f[i - 1] + f[i - 2] + ... + f[i - k] 直接矩阵优化就好了 #include <cstdio> #include <cstring> #define p 7777777 #define LL long long int n, k; struct Matrix { int n, m; LL a[11][11]; Matrix() { n = m = 0; memset(a, 0, sizeof(a)); } }; inli

[矩阵乘法][DP]Vijos1067 Warcraft III 守望者的烦恼

题目梗概 n个单位的路程,主角每次最多可以走k个单位(也就是每次可以走1-k个单位),问最后到第n个监狱的方法数. 思考 DP转移方程并不难推导: dp[i]表示第i个监狱的方法数 $dp\left [ i \right ] = dp\left [ i-1 \right ] + dp\left [ i-2 \right ]\cdots \cdots + dp\left [ i-k-1 \right ]$ 但是这个n有点太大了,所以我们需要对DP方程进行优化. 仔细观察转移方程会发现,每次都是加上

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 1 0 * b =  c 0 0 0 1    c     d 1 1 1 1    d    a+b+c+d 然后跑高速幂 #include <iostream> #include <cstdio> #include <algorithm> #include <cm

Warcraft III 守望者的烦恼

题目链接: 这道题跟斐波那契数列类似,快速幂矩阵随便推一推就出来了! #pragma GCC optimize("O3") #include <bits/stdc++.h> using namespace std; #define ll long long #define re register #define pb push_back #define fi first #define se second const int N=1e6+10; const int mod=

守望者的烦恼

OJ P1352 这道题是个很浅显的DP,根据题意我们可以得到状态转移方程: 这个方程很简单,复杂度是的,这个复杂度在这道题下显然是不可接受的.考虑优化DP方程,继续观察这个DP方程,我们发现在K=2时其本质就是斐波那契数列,所有考虑斐波那契数列的优化方法:矩阵乘法 我们设这个矩阵为A,那么显然可以得到以下的关系 那么只要可以得到A,我们就能在的复杂度内完成此题 下面给出矩阵A,具体的推理过程我也不知道 然后用快速幂优化,最后就是本题答案. 1 //OJ 1352 2 //by Cydiater