zoukankan      html  css  js  c++  java
  • Vijos P1067Warcraft 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,否则可能会溢出

     

    题解

    这道题目是矩阵,我竟然有点忘记矩阵乘法了QAQ赶快再做几题!

    代码

     1 /*Author:WNJXYK*/
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 
     6 const int M=7777777;
     7 int n,siz; 
     8 long long mul[11][11],ans[11];
     9 inline void mTimes(long long a[],long long b[][11]){
    10     long long c[11];
    11     memset(c,0,sizeof(c));
    12     for (int i=1;i<=siz;i++){
    13         for (int j=1;j<=siz;j++){
    14             c[i]=(c[i]+a[j]*b[i][j])%M;
    15         }
    16     }
    17     memcpy(a,c,sizeof(c));
    18 }
    19 inline void mTimes(long long a[][11],long long b[][11]){
    20     long long d[11][11];
    21     memset(d,0,sizeof(d));
    22     for (int i=1;i<=siz;i++){
    23         for (int j=1;j<=siz;j++){
    24             for (int k=1;k<=siz;k++){
    25                 d[i][j]=(d[i][j]+a[i][k]*b[k][j])%M;
    26             }
    27         }
    28     }
    29     memcpy(a,d,sizeof(d));
    30 }
    31 
    32 int main(){
    33     scanf("%d%d",&siz,&n);
    34     ans[0]=1;
    35     for (int i=1;i<=siz;i++){
    36         for (int j=0;j<i;j++){
    37             ans[i]+=ans[j];
    38         }
    39     }
    40     for (int i=1;i<=siz;i++)mul[siz][i]=1;
    41     for (int i=2;i<=siz;i++)mul[i-1][i]=1;
    42     n--;
    43     while(n){
    44         if (n&1) mTimes(ans,mul);
    45         n/=2;
    46         mTimes(mul,mul);
    47     }
    48     printf("%lld
    ",ans[1]);
    49     return 0;
    50 }
    View Code
  • 相关阅读:
    Java小白集合源码的学习系列:Vector
    Java小白集合源码的学习系列:LinkedList
    707.设计双向链表
    Java小白集合源码的学习系列:ArrayList
    Leetcode动态规划【简单题】
    小白学Java:老师!泛型我懂了!
    小白学Java:包装类
    Java面向对象之异常详解
    Java面向对象之异常【一】
    浅谈Java中接口与抽象类的异同
  • 原文地址:https://www.cnblogs.com/WNJXYK/p/4070804.html
Copyright © 2011-2022 走看看