zoukankan      html  css  js  c++  java
  • 矩阵快速幂(queue递推)

    http://acm.hdu.edu.cn/showproblem.php?pid=2604

    Queuing

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 8567    Accepted Submission(s): 3749


    Problem Description
    Queues and Priority Queues are data structures which are known to most computer scientists. The Queue occurs often in our daily life. There are many people lined up at the lunch time.

      Now we define that ‘f’ is short for female and ‘m’ is short for male. If the queue’s length is L, then there are 2L numbers of queues. For example, if L = 2, then they are ff, mm, fm, mf . If there exists a subqueue as fmf or fff, we call it O-queue else it is a E-queue.
    Your task is to calculate the number of E-queues mod M with length L by writing a program.
     
    Input
    Input a length L (0 <= L <= 10 6) and M.
     
    Output
    Output K mod M(1 <= M <= 30) where K is the number of E-queues with length L.
     
    Sample Input
    3 8 4 7 4 8
     
    Sample Output
    6 2 1
     
    Author
    WhereIsHeroFrom
     
    Source
     
    Recommend
    lcy   |   We have carefully selected several similar problems for you:  1588 2606 2276 2603 3117
     
    题意:有2的L次方个组合队列,求出不包含子序列fmf和fff的个数;
    思路:根据长度增长变化可发现,fn就是在f(n-1)已知序列后加上f或m变化而来。根据题意可推出
    递推式:
    fn     0 1 2 1 2    f(n-1)
    ff      0 0 0 0 1    ff(子序列的数量)
    mm    0 0 1 1 0    mm
    fm      0 1 0 0 1    fm
    mf      0 0 1 0 0    mf
     
    #include<bits/stdc++.h>
    using namespace std ;
    #define int long long 
    typedef long long ll ;
    const int N = 100009  , maxn = 4;
    int n , m ;
    int mod ;
    struct node{
    	int a[maxn][maxn];//矩阵
    	node(){memset(a , 0 , sizeof(a));}
    	node operator * (const node &B)const{
    		node C ;
    		for(int i = 0 ; i < maxn ; i++){
    			for(int j = 0 ; j < maxn ; j++){
    				for(int k =  0 ; k < maxn ; k++){
    					C.a[i][j] = (C.a[i][j] + (a[i][k] % mod * B.a[k][j] % mod) % mod) % mod;
    				}
    			}
    		}
    		return C;
    	} 
    };
    
    node qpow(node A , int b){//A矩阵的b次方
    	node C ;
    	for(int i = 0 ; i < maxn ; i++){
    		C.a[i][i] = 1 ;
    	}
    	while(b){
    		if(b&1){
    			C = C * A ; 
    		}
    		b >>= 1 ;
    		A = A * A ;
    	}
    	return C;
    }
    int a[4][4] = {{0,0,0,1},{1,0,0,1},{0,1,1,0},{0,0,1,0}};
    
    void solve(){
        if(n == 0){
            cout << 0 << endl;
            return ;
        }
        if(n == 1){
            cout << 2 << endl;
            return ;
        }
        node A , B , C;
        B.a[0][0] = B.a[1][0] = B.a[2][0] = B.a[3][0] = 1 ;
        for(int i = 0 ; i < maxn ; i ++){
            for(int j = 0 ; j < maxn ; j++){
                A.a[i][j] = a[i][j] ;
            }
        }
        C = qpow(A , n - 2) * B  ;
        int ans = 0 ;
        for(int i = 0 ; i < maxn ; i++){
            ans += C.a[i][0] ;
            ans %= mod ;
        }
        cout << ans << endl;
    }
    
    signed main(){
        #ifdef ONLINE_JUDGE
        #else
            freopen("D:\c++\in.txt", "r", stdin);
            //freopen("D:\c++\in.txt", "w", stdout);
        #endif
        //int t ;
        //scanf("%lld" , &t);
        //while(t--)
        while(cin >> n >> mod)
            solve();
    }
    

     不过这道题还有别的递推式:

    递推方程:f(n)=f(n-1)+f(n-3)+f(n-4)。

      如果第n位是f,它前面是f时(ff),再前一位必须是m(mff),再前一位还必须是m(mmff),所以有f(n-4)种;

             它前面是m时(mf),再前一位必须是m(mmf),再前就任意了,所以有f(n-3)种

      第n位是m,它前面可以是任意的,所以有f(n-1)种。

      接下来是构造矩阵:

  • 相关阅读:
    C# UrlDecode将+替换为空格问题
    Hashtable无序,用Dictionary代替
    Oracle查找Web执行SQL
    远程连接Oracle服务器
    asp.net core网站SSL nginx配置
    Supervisor踩过的坑
    centos nginx配置支持WebSocket(signalR)
    SignalR在asp.net core下使用
    Hangfire 在asp.net core环境的使用
    liteUploader上传控件的封装使用
  • 原文地址:https://www.cnblogs.com/nonames/p/11360347.html
Copyright © 2011-2022 走看看