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 }

 

posted @ 2018-04-18 21:32  _努力努力再努力x  阅读(152)  评论(0编辑  收藏  举报