zoukankan      html  css  js  c++  java
  • hdu-2604 Queuing---递推+矩阵快速幂

    题目链接:

    https://vjudge.net/problem/HDU-2604

    题目大意:

    n个人排队,f表示女,m表示男,包含子串‘fmf’和‘fff’的序列为O队列,否则为E队列,有多少个序列为E队列。

    解题思路:

    用f(n)表示n个人满足条件的结果,那么如果最后一个人是m的话,那么前n-1个满足条件即可,就是f(n-1); 
    如果最后一个是f那么这个还无法推出结果,那么往前再考虑一位:那么后三位可能是:mmf, fmf, mff, fff,其中fff和fmf不满足题意所以我们不考虑,但是如果是 
    mmf的话那么前n-3可以找满足条件的即:f(n-3);如果是mff的话,再往前考虑一位的话只有mmff满足条件即:f(n-4) 
    所以f(n)=f(n-1)+f(n-3)+f(n-4),递推会超时,可用矩阵快速幂 
    构造一个矩阵: 
    pic

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int MOD;
     4 struct Mat
     5 {
     6     int a[4][4];
     7     int n, m;//n为行数,m为列数
     8     Mat(int n, int m):n(n), m(m)
     9     {
    10         memset(a, 0, sizeof(a));
    11     }
    12     void init()
    13     {
    14         for(int i = 0; i < n; i++)a[i][i] = 1;//初始化成单位矩阵
    15     }
    16     void output()
    17     {
    18         for(int i = 0; i < n; i++)
    19         {
    20             for(int j = 0; j < m; j++)
    21             {
    22                 cout<<a[i][j]<<" ";
    23             }
    24             cout<<endl;
    25         }
    26     }
    27 };
    28 Mat mul(Mat a, Mat b)//矩阵乘法
    29 {
    30     Mat tmp(a.n, b.m);//矩阵乘法结果矩阵行数为a的行数,列数为b的列数
    31     for(int i = 0; i < a.n; i++)
    32     {
    33         for(int j = 0; j < b.m; j++)
    34         {
    35             for(int k = 0; k < a.m; k++)//a.m == b.n(乘法的前提条件)
    36             {
    37                 tmp.a[i][j] += (a.a[i][k] * b.a[k][j] % MOD);
    38                 tmp.a[i][j] %= MOD;
    39             }
    40         }
    41     }
    42     return tmp;
    43 }
    44 Mat pow(Mat a, int n)
    45 {
    46     Mat tmp(a.n, a.m);
    47     tmp.init();
    48     while(n)
    49     {
    50         if(n & 1)tmp = mul(tmp, a);
    51         n /= 2;
    52         a = mul(a, a);
    53     }
    54     return tmp;
    55 }
    56 int c[4][4] =
    57 {
    58     1,0,1,1,
    59     1,0,0,0,
    60     0,1,0,0,
    61     0,0,1,0,
    62 };
    63 int t[] = {0,2,4,6,9};
    64 int main()
    65 {
    66     Mat a(4, 4);
    67     Mat b(4, 1);
    68     memcpy(a.a, c, sizeof(c));
    69     for(int i = 0; i < 4; i++)b.a[i][0] = t[4 - i];
    70     //a.output();
    71     //b.output();
    72     int n ,k;
    73     while(cin >> n >> k)
    74     {
    75         MOD = k;
    76         if(n <= 4)
    77         {
    78             cout<<t[n]%k<<endl;
    79         }
    80         else
    81         {
    82             Mat ans = pow(a, n - 4);
    83             ans = mul(ans, b);
    84             //ans.output();
    85             cout<<ans.a[0][0]<<endl;
    86         }
    87     }
    88 }
  • 相关阅读:
    spymemcache与spring结合
    Turtle库的学习积累
    汉诺塔绘图学习
    计算圆周率π和显示进度条
    川菜 in English
    一些必不可少的Sublime Text 2插件 钟磊的专栏 博客频道 CSDN.NET
    \usepackage{natbib}在latex模板写作中的心得_格致轩_百度空间
    Geant4新版本:新安装方法,新运行方式
    ubuntu系统备份
    Latex数学公式中的空格
  • 原文地址:https://www.cnblogs.com/fzl194/p/8877733.html
Copyright © 2011-2022 走看看