昨晚搞的第二道矩阵快速幂,一开始我还想直接套个矩阵上去(原谅哥模板题做多了),后来看清楚题意后觉得有点像之前做的数位dp的水题,于是就用数位dp的方法去分析,推了好一会总算推出它的递推关系式了(还是菜鸟,对dp还是很不熟练):

  dp[i][0/1]表示以0/1开头的不含101且不含111的i位数(用1来表示f,0表示m,看着方便点),然后,状态转移方程是:

  dp[i][0]=dp[i-1][0]+dp[i-1][1];    //以0开头的话后面接什么数都不成问题

  dp[i][1]=dp[i-2][0]+dp[i-3][0];

  在这里说下第二个,以1开头的话就要考虑多一些了,首先第i-2位一定不能是1,否则第i-1位取0/1都会构成101或111,所以第i位和第i-2位就确定了(即1x0xxx...)。接下来看第i-1位,如果取0的话,那么i-2位以后去什么数都没有问题,所以此时共有dp[i-2][0]种情况;如果取1的话,那么第i-3位就不能为1了,否则第i-1,i-2,i-3就会构成101,所以第i-3位只能取0,此时有dp[i-3][0]种情况,这就是第二个递推式子。

  有了状态转移方程后,便很容易写出代码了,注意好边界的处理即可(因为涉及dp[i-3]的,所以前3个dp[i][0/1]都手算出来):

 #include<cstdio>
#include<cstring>
typedef long long LL;
int dp[][], mod;
//这个是线性递推的dp,4000+ms过的,不过也好开心了~ inline void init(int n){
dp[][]= dp[][]= %mod;
dp[][]= dp[][]= %mod;
dp[][]= %mod; dp[][]= %mod;
for(int i=; i<=n; ++i){
dp[i][]= (dp[i-][]+dp[i-][])% mod;
dp[i][]= (dp[i-][]+dp[i-][])% mod;
}
} int main(){
int L;
while(~scanf("%d%d",&L,&mod)){
init(L);
printf("%d\n",(dp[L][]+dp[L][])%mod);
}
return ;
}

  第一次提交后超时了,实际上是因为scanf函数少了个文件结束的标志,可我当时以为是算法的问题,又因为一开始就知道这道题是和矩阵快速幂有关的,所以只好构建矩阵来做了。把刚刚的递推关系整理了下:

  dp[i][0]=dp[i-1][0]+dp[i-3][0]+dp[i-4][0];    //结合第2个式子可以得出的

  dp[i][1]=dp[i-2][0]+dp[i-3][0];

  所以有dp[i][0]=1*dp[i-1][0]+0*dp[i-2][0]+1*dp[i-3][0]+1*dp[i-4][0];

  四阶的,系数分别为1,0,1,1,所以有 [dp[i],dp[i-1],dp[i-2],dp[i-3] ]= A* [ dp[i-1],dp[i-2],dp[i-3],dp[i-4] ]T,其中矩阵 A =

1 0 1 1
1 0 0 0
0 1 0 0
0 0 1 0

  代码如下:

 #include<cstdio>
#include<cstring>
int mod;
//在推出线性递推关系后构造矩阵来做,在一些细节问题上调试了好久,
//最后却因为scanf函数没写好返回超时 T.T,幸好最后幸运地发现了
//最后以500+ms过了,就不明白杭电上那些几十ms过的人究竟是怎么做的! struct matrix{
int c[][],n;
matrix(int n=):n(n) { memset(c,,sizeof(c)); }
void identity(){
for(int i=; i<=n; ++i) c[i][i]= ;
}
matrix operator *(const matrix &m2) const {
matrix mul(n);
for(int i=; i<=n; ++i)
for(int j=; j<=n; ++j)
for(int k=; k<=n; ++k)
mul.c[i][j]= (mul.c[i][j]+c[i][k]*m2.c[k][j]%mod)%mod;
return mul;
}
} A(); matrix quick_mod(matrix m, int b){
matrix res(m.n);
res.identity();
while(b){
if(b&) res= res*m;
m= m*m;
b>>=;
}
return res;
} inline int dp_i0(int i){
int dp[]= {,,,,};
if(i<) return ;
if(i<=) return dp[i];
matrix tmp= quick_mod(A,i-);
return (tmp.c[][]*dp[]%mod +tmp.c[][]*dp[]%mod +tmp.c[][]*dp[]%mod +tmp.c[][]*dp[]%mod)%mod;
} int main()
{
A.c[][]= A.c[][]= A.c[][]= ;
A.c[][]= A.c[][]= A.c[][]= ;
int L;
while(~scanf("%d%d",&L,&mod)){
int ans[]= {,,,};
if(L<=) { printf("%d\n",ans[L]%mod); continue ; } int dp_L0= dp_i0(L);
int dp_L1= (dp_i0(L-)+dp_i0(L-))%mod;
printf("%d\n",(dp_L0+dp_L1)%mod);
}
return ;
}

  还是因为一些细节问题调试了好久,第一次提交后还是超时,无意中翻翻其他人的代码忽然看到那个scanf函数才猛然发觉自己的scanf函数没有文件结束的标志,改之,最后500+ms过了,果然logn的算法就是快啊~然后上面那个直接递推的代码也是同样的问题,改后提交也AC了,但却是4000+ms卡过的,看来后台数据应该是很多的,所以10^6的O(n)做法还是很接近时限的边缘……不过我还是不明白杭电上那些几十ms过的人到底是怎么做的!

hdu 2604 Queuing(dp递推)的更多相关文章

  1. hdu 2604 Queuing dp找规律 然后矩阵快速幂。坑!!

    http://acm.hdu.edu.cn/showproblem.php?pid=2604 这题居然O(9 * L)的dp过不了,TLE,  更重要的是找出规律后,O(n)递推也过不了,TLE,一定 ...

  2. HDU 2154 跳舞毯 | DP | 递推 | 规律

    Description 由于长期缺乏运动,小黑发现自己的身材臃肿了许多,于是他想健身,更准确地说是减肥. 小黑买来一块圆形的毯子,把它们分成三等分,分别标上A,B,C,称之为“跳舞毯”,他的运动方式是 ...

  3. HDU 5860 Death Sequence(递推)

    HDU 5860 Death Sequence(递推) 题目链接http://acm.split.hdu.edu.cn/showproblem.php?pid=5860 Description You ...

  4. HDU 2085 核反应堆 --- 简单递推

    HDU 2085 核反应堆 /* HDU 2085 核反应堆 --- 简单递推 */ #include <cstdio> ; long long a[N], b[N]; //a表示高能质点 ...

  5. hdu2089(数位DP 递推形式)

    不要62 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  6. HDU 2604 Queuing,矩阵高速幂

    题目地址:HDU 2604 Queuing 题意:  略 分析: 易推出:   f(n)=f(n-1)+f(n-3)+f(n-4) 构造一个矩阵: 然后直接上板子: /* f[i] = f[i-1] ...

  7. HDU - 2604 Queuing(递推式+矩阵快速幂)

    Queuing Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  8. HDU 2604 Queuing(递推+矩阵)

    Queuing [题目链接]Queuing [题目类型]递推+矩阵 &题解: 这题想是早就想出来了,就坑在初始化那块,只把要用的初始化了没有把其他的赋值为0,调了3,4个小时 = = 本题是可 ...

  9. [hdu 2604] Queuing 递推 矩阵快速幂

    Problem Description Queues and Priority Queues are data structures which are known to most computer ...

随机推荐

  1. MongoDB在windows自启动

    D:\mongodb\Server\3.0\bin>mongod --logpath D:\mongodb\log\mongo.log --logappend--dbpath D:\mongod ...

  2. Uva 11754 Code Feat

    题意概述: 有一个正整数$N$满足$C$个条件,每个条件都形如“它除以$X$的余数在集合$\{Y_1, Y_2, ..., Y_k\}$中”,所有条件中的$X$两两互质, 你的任务是找出最小的S个解. ...

  3. 欧拉回路-Door Man 分类: 图论 POJ 2015-08-06 10:07 4人阅读 评论(0) 收藏

    Door Man Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 2476 Accepted: 1001 Description ...

  4. JAVA基础知识之IO-File类

    File类介绍 File是java.io包下面的一个类,代表与平台无关的文件或者目录.JAVA中,无论文件还是目录,都可以看作File类的一个对象.File类能对文件或目录新建,删除,获取属性等操作, ...

  5. spoj 3871. GCD Extreme 欧拉+积性函数

    3871. GCD Extreme Problem code: GCDEX Given the value of N, you will have to find the value of G. Th ...

  6. uva 10673 Play with Floor and Ceil

    Problem APlay with Floor and CeilInput: standard inputOutput: standard outputTime Limit: 1 second Th ...

  7. java提高篇---HashMap

    HashMap也是我们使用非常多的Collection,它是基于哈希表的 Map 接口的实现,以key-value的形式存在.在HashMap中,key-value总是会当做一个整体来处理,系统会根据 ...

  8. wpfのpack协议

    当引用的资源需要做成dll时,要用此协议 协议:pack://      授权:有两种.一种用于访问编译时已经知道的文件,用application:///.一种用于访问编译时不知道.运行时才知道的文件 ...

  9. java实现UDP协议传输DatagramSocket

    摘自:http://blog.csdn.net/wintys/article/details/3525643/ Server端. package com.topca.server; import ja ...

  10. iOS:堆(heap)和栈(stack)的理解

    Objective-C的对象在内存中是以堆的方式分配空间的,并且堆内存是由你释放的,即release 栈由编译器管理自动释放的,在方法中(函数体)定义的变量通常是在栈内,因此如果你的变量要跨函数的话就 ...