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

    题解:

    设dp[i],表示跳到i节点的方案数,显然dp[i]=sigam dp[j](i>j>=max(i-k,0))意思就是说可以从这些节点跳过来,所以这其实只是一个递推而已,所以我们可以开两个k*k的矩阵,用矩阵快速幂来解决,所以初始矩阵就是把dp[0]填到a[1][k]的位置,目标矩阵的最上面一行都是dp[i~i-k],每次*一次i就加1,(当然快速幂优化),转移矩阵就可以通过目标矩阵写出来了。

    代码:

    #include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    #define mod 7777777
    using namespace std;
    struct jvzhen{
        ll s[17][17];
    }a,b;
    int n,k;
    
    jvzhen jvcheng(jvzhen x,jvzhen y){
        jvzhen c;
        memset(c.s,0,sizeof(c.s));
        for(int i=1;i<=k;i++)
        for(int j=1;j<=k;j++)
        for(int kk=1;kk<=k;kk++)
        c.s[i][j]+=x.s[i][kk]*y.s[kk][j],c.s[i][j]%=mod;
        return c;
    }
    
    int main(){
        scanf("%d%d",&k,&n);
        memset(a.s,0,sizeof(a.s));
        memset(b.s,0,sizeof(b.s));
        a.s[1][k]=1;
        for(int i=1;i<k;i++) b.s[i+1][i]=1;
        for(int i=1;i<=k;i++) b.s[i][k]=1;
        while(n){
            if(n&1) a=jvcheng(a,b);
            b=jvcheng(b,b);
            n>>=1;
        }
        printf("%lld",a.s[1][k]);
    } 
  • 相关阅读:
    使用CustomValidate自定义验证控件
    C#中金额的大小写转换
    Andriod出错之Unable to build: the file dx.jar was not loaded from the SDK folder!
    VC 编写的打字练习
    机房工作笔记Ping只有单向通
    web服务协同学习笔记(1)
    Dll 学习3 将MDI子窗口封装在DLL中
    机房工作学习文件共享
    Andriod出错之Failed to find an AVD compatible with target 'Android 2.2'
    Andriod出错之wrapper was not properly loaded first
  • 原文地址:https://www.cnblogs.com/renjianshige/p/7357680.html
Copyright © 2011-2022 走看看