zoukankan      html  css  js  c++  java
  • hdu 1757 A Simple Math Problem (构造矩阵解决递推式问题)

    题意:有一个递推式f(x)

    当 x < 10    f(x) = x.
    当 x >= 10  f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10)

    同时ai(0<=i<=9) 不是 0 就是 1;

    现在给你 ai 的数字,以及k和mod,请你算出 f(x)%mod 的结果是多少

    思路:线性递推关系是组合计数中常用的一种递推关系,如果直接利用递推式,需要很长的时间才能计算得出,时间无法承受,但是现在我们已知  f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10),那么我们可以根据这个式子构造一个矩阵来解决这得问题

    Fn=A×Fn-1 ,其中Fn={f(x-10)  ,A={0 1 0 0 0 0 0 0 0 0 0

                                  f(x-9)           0 0 1 0 0 0 0 0 0 0 0 

                                  f(x-8)           0 0 0 1 0 0 0 0 0 0 0 

                                  ........           .................

                                  f(x)}            0 a9 a8 a7 ........... a0}

    在利用矩阵快速幂一顿套模板,最后得到矩阵ANS,和ANS中的a0' a1'....a9',我们最后的答案就是a0'*f(9)+a2'*f(8)...a9'*f(0);

    代码:

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    
    using namespace std;
    
    typedef long long ll;
    const int N=11,M=11,P=11;
    //const int MOD=1000000007;
    int MOD;
    struct  Matrix
    {
        ll m[N][N];
    };
    
    Matrix A;
    Matrix I;
    
    Matrix multi(Matrix a,Matrix b)
    {
        Matrix ans;
        for(int i=0;i<N;i++)
        {
           for(int j=0;j<M;j++)
           {
              ans.m[i][j]=0;
              for(int k=0;k<P;k++)
              {
                 ans.m[i][j]+=a.m[i][k]*b.m[k][j]%MOD;
              }
              ans.m[i][j]%=MOD;
           }
        }
        return ans;
    }
    
    Matrix power(Matrix a,int k)
    {
        Matrix ans=I,p=a;
        while(k)
        {
          if(k&1)
          {
            ans=multi(ans,p);
          }
          k>>=1;
          p=multi(p,p);
        }
        return ans;
    }
    
    int main(int argc, char const *argv[])
    {
        int a[10];
        ll k;
        while(scanf("%lld %lld",&k,&MOD)!=-1)
        {
           for(int i=0;i<10;i++)
           {
             scanf("%d",&a[i]);
           }
           for(int i=0;i<N;i++)
           {
              for(int j=0;j<M;j++)
              {
                 I.m[i][j]=0;
                 if(i==j)
                 {
                    I.m[i][j]=1;
                 }
              }
           }
           for(int i=0;i<N-1;i++)
           {
              for(int j=0;j<M;j++)
              {
                  A.m[i][j]=0;
                  if(i+1==j)
                  {
                    A.m[i][j]=1;
                  }
              }
           }
           A.m[N-1][0]=0;
           for(int i=1;i<N;i++)
           {
              A.m[N-1][i]=a[10-i];
           }
           Matrix ans = power(A,k-9);
           ll num=0;
           for(int i=N-1;i>=1;i--)
           {
               num=(num+ans.m[N-1][i]*(i-1))%MOD;
           }
           cout<<num<<endl;
        }
        return 0;
    }
  • 相关阅读:
    Struts2 Hello World
    Struts2入门(1)
    Struts2_day01
    Java Web Model2实战
    Oracle_day04
    SAP调用外部webservice接口
    通用清账程序
    服务器IDOC文件解析程序
    IDOC接口创建步骤
    SAP 本地发送IDOC
  • 原文地址:https://www.cnblogs.com/simplekinght/p/6662117.html
Copyright © 2011-2022 走看看