zoukankan      html  css  js  c++  java
  • HDU 4602 Partition (矩阵乘法)

    Partition

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 797    Accepted Submission(s): 322


    Problem Description
    Define f(n) as the number of ways to perform n in format of the sum of some positive integers. For instance, when n=4, we have
      4=1+1+1+1
      4=1+1+2
      4=1+2+1
      4=2+1+1
      4=1+3
      4=2+2
      4=3+1
      4=4
    totally 8 ways. Actually, we will have f(n)=2(n-1) after observations.
    Given a pair of integers n and k, your task is to figure out how many times that the integer k occurs in such 2(n-1) ways. In the example above, number 1 occurs for 12 times, while number 4 only occurs once.
     
    Input
    The first line contains a single integer T(1≤T≤10000), indicating the number of test cases.
    Each test case contains two integers n and k(1≤n,k≤109).
     
    Output
    Output the required answer modulo 109+7 for each test case, one per line.
     
    Sample Input
    2 4 2 5 5
     
    Sample Output
    5 1
     
    Source
     
    Recommend
    liuyiding
     

    思路:

    列出了 n=5 时 5,4,3,2,1 出现的次数为 1 2 5 12 28
    f[n+1]=3*f[n]-f[n-1]-f[n-2]-..f[1]
    f[n]=3*f[n-1]-f[n-2]-..f[1]
    ==> f[n+1]=4*f[n]-4*f[n-1]


    #include<iostream>
    #include<cstdio>
    #include<cstring>
    
    using namespace std;
    
    const int mod=1000000007;
    
    struct Matrix{
        long long arr[2][2];
    };
    
    Matrix init,unit;
    int n,k;
    long long num[2][2]={{4,-4},{1,0}};
    
    void Init(){
        for(int i=0;i<2;i++)
            for(int j=0;j<2;j++){
                init.arr[i][j]=num[i][j];
                unit.arr[i][j]=(i==j)?1:0;
            }
    }
    
    Matrix Mul(Matrix a,Matrix b){
        Matrix c;
        for(int i=0;i<2;i++)
            for(int j=0;j<2;j++){
                c.arr[i][j]=0;
                for(int k=0;k<2;k++)
                    c.arr[i][j]=(c.arr[i][j]%mod+a.arr[i][k]*b.arr[k][j]%mod+mod)%mod;
                c.arr[i][j]%=mod;
            }
        return c;
    }
    
    Matrix Pow(Matrix a,Matrix b,int k){
        while(k){
            if(k&1){
                b=Mul(a,b);
            }
            a=Mul(a,a);
            k>>=1;
        }
        return b;
    }
    
    int main(){
    
        //freopen("input.txt","r",stdin);
    
        int t;
        scanf("%d",&t);
        while(t--){
            scanf("%d%d",&n,&k);
            Init();
            if(k>n){
                printf("0
    ");
                continue;
            }
            int tmp=n-k+1;
            if(tmp==1){
                printf("1
    ");
                continue;
            }
            if(tmp==2){
                printf("2
    ");
                continue;
            }
            if(tmp==3){
                printf("5
    ");
                continue;
            }
            Matrix res=Pow(init,unit,tmp-3);
            //long long ans=((res.arr[0][0]%mod*5)%mod+(res.arr[0][1]%mod*2)%mod)%mod;
            long long ans=(res.arr[0][0]*5+res.arr[0][1]*2)%mod;
            cout<<ans<<endl;
        }
        return 0;
    }


  • 相关阅读:
    宏定义中的#
    HDU1506 Largest Rectangle in a Histogram 动态规划
    HDU1864 最大报销额 DP
    POJ2771 Guardian of Decency 最大独立子集
    POJ1698 Alice's Chance 最大流
    HDU1003 Max Sum 动态规划
    eval格式化事件类型的字符串
    C#虚方法virtual详解
    c# 利用反射获得某个类或者对象的所有属性
    windows服务的通常写法
  • 原文地址:https://www.cnblogs.com/jackge/p/3210870.html
Copyright © 2011-2022 走看看