HDU - 2604 Queuing(矩阵快速幂或直接递推)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2604

题意:给出字符串长度L,并且字符串只由‘f‘,‘m‘构成,有2^L种情况,问在其中不包含‘fmf‘,‘fff‘的字符串有多少个。

1.直接递推,虽然过了,但是数据稍微大点就很可能TLE,因为代码上交上去耗时还是比较长的(感觉数据有点水)╭(′▽`)╭(′▽`)╯(

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5
 6 int a[1111111];
 7
 8 int main(){
 9     int l,m;
10     while(scanf("%d %d",&l,&m)!=EOF){
11         a[0]=1;a[1]=2;a[2]=4;a[3]=6;
12         if(l>=4){
13             for(int i=4;i<=l;i++){
14                 a[i]=a[i-1]+a[i-3]+a[i-4];
15                 a[i]%=m;
16             }
17             printf("%d\n",a[l]);
18         }
19         else printf("%d\n",a[l]%m);
20     }
21     return 0;
22 }

2.用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),接着就很简单了,和斐波那契的递推式很像。

网上找的一张图,(-?-;),就是这个矩阵。因为f0=1,其实可以n从4就开始取了。

 1 #include <iostream>
 2 #include <cstring>
 3 using namespace std;
 4
 5 struct matrix{
 6     int m[4][4];
 7 }ans,base;
 8
 9 int TnT[5]={1,2,4,6,9};
10
11 int MOD;
12 matrix multi(matrix a,matrix b){
13     matrix temp;
14     memset(temp.m,0,sizeof(temp.m));
15     for(int i=0;i<4;i++){
16         for(int j=0;j<4;j++){
17             for(int k=0;k<4;k++){
18                 temp.m[i][j]+=a.m[i][k]*b.m[k][j];
19                 if(temp.m[i][j]>=MOD) temp.m[i][j]%=MOD;
20             }
21         }
22     }
23     return temp;
24 }
25
26 void init(){
27     for(int i=0;i<4;i++)
28     for(int j=0;j<4;j++)
29     ans.m[i][j]=(i==j);
30     for(int i=0;i<4;i++) base.m[0][i]=1;
31     base.m[0][1]=0;
32     for(int i=1;i<4;i++) base.m[i][i-1]=1;
33 }
34
35 int fast_mod(int n){
36     init();
37     while(n>0){
38         if(n&1) ans=multi(ans,base);
39         base=multi(base,base);
40         n>>=1;
41     }
42     int res=0;
43     for(int i=0;i<4;i++) res+=ans.m[0][i]*TnT[4-i]%MOD;
44     return res%MOD;
45 }
46
47 int main(){
48     int n,m;
49     while(cin>>n>>m){
50         memset(ans.m,0,sizeof(ans.m));
51         memset(base.m,0,sizeof(base.m));
52         MOD=m;
53         if(n<=4) cout<<TnT[n]%MOD<<endl;
54         else cout<<fast_mod(n-4)<<endl;
55     }
56     return 0;
57 }
时间: 2024-10-29 16:10:31

HDU - 2604 Queuing(矩阵快速幂或直接递推)的相关文章

HDU 2604 Queuing 矩阵高速幂

QueuingTime Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2483    Accepted Submission(s): 1169 Problem Description Queues and Priority Queues are data structures which are known to most computer s

HDU 5863 cjj&#39;s string game ( 16年多校10 G 题、矩阵快速幂优化线性递推DP )

题目链接 题意 : 有种不同的字符,每种字符有无限个,要求用这k种字符构造两个长度为n的字符串a和b,使得a串和b串的最长公共部分长度恰为m,问方案数 分析 : 直觉是DP 不过当时看到 n 很大.但是 m 很小的时候 发现此题DP并不合适.于是想可能是某种组合数学的问题可以直接公式算 看到题解的我.恍然大悟.对于这种数据.可以考虑一下矩阵快速幂优化的DP 首先要想到线性递推的 DP 式子 最直观的想法就是 dp[i][j] = 到第 i 个位置为止.前面最长匹配长度为 j 的方案数 但是如果仔

矩阵快速幂优化线性递推

我们熟知的斐波那契数列递推公式是: \(f(n)=f(n-1)+f(n-2)\) 假设我们需要求斐波那契数列的第n项,当n非常大(如n=1e9)的时候,递推肯定超时.我们不妨设: \(\binom{f_{n}}{f_{n-1}}=\begin{pmatrix}a & b\\ c & d\end{pmatrix}\binom{f_{n-1}}{f_{n-2}}\) 将等式右边乘开,得到: \(\binom{af_{n-1}+bf_{n-2}}{cf_{n-1}+df_{n-2}}\) 要使其

Hdu 4965(矩阵快速幂)

题目链接 Fast Matrix Calculation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 87    Accepted Submission(s): 39 Problem Description One day, Alice and Bob felt bored again, Bob knows Alice is a

ZOJ 3690 &amp; HDU 3658 (矩阵快速幂+公式递推)

ZOJ 3690 题意: 有n个人和m个数和一个k,现在每个人可以选择一个数,如果相邻的两个人选择相同的数,那么这个数要大于k 求选择方案数. 思路: 打表推了很久的公式都没推出来什么可行解,好不容易有了想法结果WA到天荒地老也无法AC.. 于是学习了下正规的做法,恍然大悟. 这道题应该用递推 + 矩阵快速幂. 我们设F(n) = 有n个人,第n个人选择的数大于k的方案数: G(n) = 有n个人,第n个人选择的数小于等于k的方案数: 那么递推关系式即是: F(1)=m?k,G(1)=k F(n

HDU 1575 &amp;&amp; 1757 矩阵快速幂&amp;&amp;构造矩阵入门

HDU 1575 Tr A Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2912    Accepted Submission(s): 2167 Problem Description A为一个方阵,则Tr A表示A的迹(就是主对角线上各项的和),现要求Tr(A^k)%9973. Input 数据的第一行是一个T,表示有T组数据.每组

hdu 6198(矩阵快速幂)

number number number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 175    Accepted Submission(s): 119 暴力发现当4 12 33 88 232 和斐波那契数列对比  答案为 第2*k+3个数减1 直接用矩阵快速幂求的F[2*k+3]  然后减1 A=1,B=0; 然后矩阵快速幂2*k

HDU 1575-Tr A(矩阵快速幂)

Tr A Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3169    Accepted Submission(s): 2367 Problem Description A为一个方阵,则Tr A表示A的迹(就是主对角线上各项的和),现要求Tr(A^k)%9973. Input 数据的第一行是一个T,表示有T组数据. 每组数据的第一行有

2017 ACM/ICPC Asia Regional Shenyang Online:number number number hdu 6198【矩阵快速幂】

Problem Description We define a sequence F: ? F0=0,F1=1;? Fn=Fn?1+Fn?2 (n≥2). Give you an integer k, if a positive number n can be expressed byn=Fa1+Fa2+...+Fak where 0≤a1≤a2≤?≤ak, this positive number is mjf?good. Otherwise, this positive number is