hdu 2604 Queuing(dp递推)
昨晚搞的第二道矩阵快速幂,一开始我还想直接套个矩阵上去(原谅哥模板题做多了),后来看清楚题意后觉得有点像之前做的数位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] ]T = 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递推)的更多相关文章
- hdu 2604 Queuing dp找规律 然后矩阵快速幂。坑!!
http://acm.hdu.edu.cn/showproblem.php?pid=2604 这题居然O(9 * L)的dp过不了,TLE, 更重要的是找出规律后,O(n)递推也过不了,TLE,一定 ...
- HDU 2154 跳舞毯 | DP | 递推 | 规律
Description 由于长期缺乏运动,小黑发现自己的身材臃肿了许多,于是他想健身,更准确地说是减肥. 小黑买来一块圆形的毯子,把它们分成三等分,分别标上A,B,C,称之为“跳舞毯”,他的运动方式是 ...
- HDU 5860 Death Sequence(递推)
HDU 5860 Death Sequence(递推) 题目链接http://acm.split.hdu.edu.cn/showproblem.php?pid=5860 Description You ...
- HDU 2085 核反应堆 --- 简单递推
HDU 2085 核反应堆 /* HDU 2085 核反应堆 --- 简单递推 */ #include <cstdio> ; long long a[N], b[N]; //a表示高能质点 ...
- hdu2089(数位DP 递推形式)
不要62 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- HDU 2604 Queuing,矩阵高速幂
题目地址:HDU 2604 Queuing 题意: 略 分析: 易推出: f(n)=f(n-1)+f(n-3)+f(n-4) 构造一个矩阵: 然后直接上板子: /* f[i] = f[i-1] ...
- HDU - 2604 Queuing(递推式+矩阵快速幂)
Queuing Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- HDU 2604 Queuing(递推+矩阵)
Queuing [题目链接]Queuing [题目类型]递推+矩阵 &题解: 这题想是早就想出来了,就坑在初始化那块,只把要用的初始化了没有把其他的赋值为0,调了3,4个小时 = = 本题是可 ...
- [hdu 2604] Queuing 递推 矩阵快速幂
Problem Description Queues and Priority Queues are data structures which are known to most computer ...
随机推荐
- MongoDB在windows自启动
D:\mongodb\Server\3.0\bin>mongod --logpath D:\mongodb\log\mongo.log --logappend--dbpath D:\mongod ...
- Uva 11754 Code Feat
题意概述: 有一个正整数$N$满足$C$个条件,每个条件都形如“它除以$X$的余数在集合$\{Y_1, Y_2, ..., Y_k\}$中”,所有条件中的$X$两两互质, 你的任务是找出最小的S个解. ...
- 欧拉回路-Door Man 分类: 图论 POJ 2015-08-06 10:07 4人阅读 评论(0) 收藏
Door Man Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 2476 Accepted: 1001 Description ...
- JAVA基础知识之IO-File类
File类介绍 File是java.io包下面的一个类,代表与平台无关的文件或者目录.JAVA中,无论文件还是目录,都可以看作File类的一个对象.File类能对文件或目录新建,删除,获取属性等操作, ...
- 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 ...
- uva 10673 Play with Floor and Ceil
Problem APlay with Floor and CeilInput: standard inputOutput: standard outputTime Limit: 1 second Th ...
- java提高篇---HashMap
HashMap也是我们使用非常多的Collection,它是基于哈希表的 Map 接口的实现,以key-value的形式存在.在HashMap中,key-value总是会当做一个整体来处理,系统会根据 ...
- wpfのpack协议
当引用的资源需要做成dll时,要用此协议 协议:pack:// 授权:有两种.一种用于访问编译时已经知道的文件,用application:///.一种用于访问编译时不知道.运行时才知道的文件 ...
- java实现UDP协议传输DatagramSocket
摘自:http://blog.csdn.net/wintys/article/details/3525643/ Server端. package com.topca.server; import ja ...
- iOS:堆(heap)和栈(stack)的理解
Objective-C的对象在内存中是以堆的方式分配空间的,并且堆内存是由你释放的,即release 栈由编译器管理自动释放的,在方法中(函数体)定义的变量通常是在栈内,因此如果你的变量要跨函数的话就 ...