zoukankan      html  css  js  c++  java
  • Krypton Number System uva 11651(dp+矩阵快速幂)

    题目链接

    题意:给定进制base,和分数score,求在base进制下,有多少个数的值为score,要求不能有连续相同的数字以及前导0.计算一个数的值即为相邻两位数的差平方的和。

    思路:因为score很大,所以直接dp肯定超时,但是即使对于base=6的情况,每次新添一个数score最大增加25(0-5),所以用dp[i][j]预处理出base平方以内的总数,然后用矩阵快速幂计算。

    #include <bits/stdc++.h>
    using namespace std;
    #define ll unsigned long long
    const int maxn=160;
    const ll mod=(1ull<<32);
    struct Marix{//矩阵
        ll mo[maxn][maxn],n;
        Marix(){}
        Marix(int _n){
            n=_n;
            for(int i=0;i<n;i++){
                for(int j=0;j<n;j++) mo[i][j]=0;
            }
        }
    };
    Marix mul(Marix a,Marix b){//矩阵乘法
        Marix res=Marix(a.n);
        for(int i=0;i<a.n;i++){
            for(int j=0;j<a.n;j++){
                for(int k=0;k<a.n;k++){
                    int tmp=(ll)a.mo[i][k]*b.mo[k][j]%mod;
                    res.mo[i][j]=(res.mo[i][j]+tmp)%mod;
                }
            }
        }
        return res;
    }
    Marix powMod(Marix a,int n){//矩阵快速幂
        Marix nul;
        nul=Marix(a.n);
        for(int i=0;i<nul.n;i++){
            nul.mo[i][i]=1;
        }
        while(n){
            if(n&1) nul=mul(nul,a);
            a=mul(a,a);
            n>>=1;
        }
        return nul;
    }
    ll n,dp[maxn][maxn],k,m;
    int main()
    {
        int t;
        int u=0;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%llu%llu",&m,&k);
            printf("Case %d: ",++u);
            n=(m-1)*(m-1);
            memset(dp,0,sizeof(dp));
            for(int i=0;i<=n;i++)
            {
                dp[0][i]=1;
            }
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<m;j++)
                {
                    for(int k=0;k<m;k++)
                    {
                        int f=(j-k)*(j-k);
                        if(i+f>n||f==0)
                        continue;
                        dp[i+f][j]=(dp[i+f][j]+dp[i][k])%mod;
                    }
                }
            }
            ll ans=0;
            if(k<=n)
            {
                for(int i=1;i<m;i++)
                {
                    ans=(ans+dp[k][i])%mod;
                }
            }
            else
            {
                Marix ret=Marix(n*m);
                for(int i=1;i<n;i++)
                {
                    for(int j=0;j<m;j++)
                    {
                        ret.mo[(i-1)*m+j][0]=dp[i][j];
                    }
                }
                ret=powMod(ret,k-n);
                for(int i=1;i<m;i++)
                {
                    ans=(ans+ret.mo[(n-1)*m+i][0])%mod;
                }
            }
            printf("%llu
    ",ans);
        }
     } 
  • 相关阅读:
    第三方库添加记录
    xcode之语法高亮效果消失解决办法
    将excel记录导入ms sql
    eWebEditor在IE8,IE7下所有按钮无效之解决办法
    关于对数据库中重复记录的操作
    javascript如何取得RadioButtonList的值
    水晶报表分页并自动插入空白行
    如何防止SQL注入
    VC++视频教程下载地址
    如何显示最近过生日的记录
  • 原文地址:https://www.cnblogs.com/2462478392Lee/p/13750106.html
Copyright © 2011-2022 走看看