zoukankan      html  css  js  c++  java
  • Little Witch Academia 题解(矩阵快速幂)

    题目链接

    题目思路

    感觉官方题解写的很好,直接放官方题解

    为什么与斐波那契数列同阶呢,可以设(dp[i])为长度为(i)的方案数

    那么转移方程即为(dp[i]=dp[i-a]+dp[i-b]),显然和斐波那契数同阶

    代码

    #include<bits/stdc++.h>
    #define debug printf("
     I am here
    ");
    #define fi first
    #define se second
    #define pii pair<int,int>
    typedef long long ll;
    const int maxn=2e2+5,inf=0x3f3f3f3f,mod=1e9+7;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    using namespace std;
    int a,b,w,h;
    int cnt=0;
    bool vis[maxn];
    vector<int> vec[maxn];
    vector<int> s;
    struct matrix{
        ll a[maxn][maxn];
    }base,ans;
    matrix mul(matrix a,matrix b,int n){
        matrix temp;
        memset(temp.a,0,sizeof(temp.a)); //一定1要清空
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                for(int k=1;k<=n;k++){
                    temp.a[i][k]+=(a.a[i][j])*(b.a[j][k]);
                    temp.a[i][k]%=mod;
                }
            }
        }
        return temp;
    }
    void qpow(ll n,ll b){
        while(b){
            if(b&1){
                ans=mul(ans,base,n);
            }
            base=mul(base,base,n);
            b=b>>1;
        }
    }
    void dfs(int temp){
        if(temp>w) return ;
        if(temp==w){
            vec[++cnt]=s;
            return ;
        }
        s.push_back(a);
        dfs(temp+a);
        s.pop_back();
        s.push_back(b);
        dfs(temp+b);
        s.pop_back();
    }
    bool check(int x,int y){
        for(int i=1;i<=w;i++){
            vis[i]=0;
        }
        int temp=0;
        for(int i=0;i<vec[x].size();i++){
            temp+=vec[x][i];
            vis[temp]=1;
        }
        temp=0;
        for(int i=0;i<vec[y].size();i++){
            temp+=vec[y][i];
            if(temp!=w&&vis[temp]){
                return 0;
            }
        }
        return 1;
    }
    int main(){
        int _;scanf("%d",&_);
        while(_--){
            scanf("%d%d%d%d",&a,&b,&w,&h);
            cnt=0;
            dfs(0);
            for(int i=1;i<=cnt;i++){
                for(int j=1;j<=cnt;j++){
                    if(check(i,j)){
                        base.a[i][j]=1;
                    }else{
                        base.a[i][j]=0;
                    }
                    if(i==j){
                        ans.a[i][j]=1;
                    }else{
                        ans.a[i][j]=0;
                    }
                }
            }
            qpow(cnt,h-1);
            ll pr=0;
            for(int i=1;i<=cnt;i++){
                for(int j=1;j<=cnt;j++){
                    pr=(pr+ans.a[i][j])%mod;
                }
            }
            printf("%lld
    ",pr);
        }
        return 0;
    }
    
    
    卷也卷不过,躺又躺不平
  • 相关阅读:
    小学数学计算出题小程序(Excel版)
    网页自动化测试技术---SeleniumBasic(VBA网页外挂)
    ODBC链接数据源(PQ学习)
    WPF动态绑定矢量图标
    由数据转为树杈的js 和由一个子节点的id获取所有的父类的id
    面试上机题目--采用vue实现以下页面效果
    html前端上机面试题
    在vue项目中的跨域解决办法
    vue-quill-editor富文本编辑器使用
    vue项目eslint配置 以及 解释
  • 原文地址:https://www.cnblogs.com/hunxuewangzi/p/14882249.html
Copyright © 2011-2022 走看看