首页 > 代码库 > Vijos 1067Warcraft III 守望者的烦恼

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

来源

杜杜我爱你个人原创

<style>pre.cjk { font-family: "Droid Sans Fallback", monospace } p { margin-bottom: 0.25cm; line-height: 120% }</style>
注意矩阵的对应项之间的关系,初始化,以及开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 }

 

 

Vijos 1067Warcraft III 守望者的烦恼