昨晚搞的第二道矩阵快速幂,一开始我还想直接套个矩阵上去(原谅哥模板题做多了),后来看清楚题意后觉得有点像之前做的数位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. 杭电1020-Encoding

    Problem Description Given a string containing only 'A' - 'Z', we could encode it using the following ...

  2. 关于iframe嵌套、动态获取iframe内的url、父页面重定向

    1 $(function () { 2 //选择器是选择了easyui中的点击链接,出现新的iframe 3 $("a[target='mainFrame']").click(fu ...

  3. 使用 MNIST 图像识别数据集

    机器学习领域中最迷人的主题之一是图像识别 (IR). 使用红外系统的示例包括使用指纹或视网膜识别的计算机登录程序和机场安全系统的扫描乘客脸寻找某种通缉名单上的个人.MNIST 数据集是可用于实验的简单 ...

  4. 2015-11-04 asp.net 弹出式日历控件 选择日期 Calendar控件

    html代码: <%@ Page Language="C#" CodeFile="calendar.aspx.cs" Inherits="cal ...

  5. Linux多线程同步机制

    http://blog.163.com/he_junwei/blog/static/19793764620141711130253/ http://blog.csdn.net/h_armony/art ...

  6. Java多线程的三种实现方式

    java多线程的三种实现方式 一.继承Thread类 二.实现Runnable接口 三.使用ExecutorService, Callable, Future 无论是通过继承Thread类还是实现Ru ...

  7. Entity Framework 第三篇 实体特性声明

    Entity Framework中对实体的特性声明有着严格的要求 1.实体必须要有主键特性,但是如果实体没有主键特性那怎么办? public int ExecuteSqlCommand(string ...

  8. asp.net webapi初探(一)

    本人对webapi尚没有深入研究,初次接触发现了在数据请求时的几点现象. 先切入代码 1.如果action中开头带有Get默认就是get方式,不带Get默认就是post方式 public string ...

  9. MVC 直接把数据库的数据输出到view(太神奇了)

    @model IEnumerable<MvcApplication32.Models.UserInfo> 后台是集合类型了 ,传到前台是model了,用 IEnumerable<&g ...

  10. (1)定义一个接口CanFly,描述会飞的方法public void fly(); (2)分别定义类飞机和鸟,实现CanFly接口。 (3)定义一个测试类,测试飞机和鸟,在main方法中创建飞机对象和鸟对象, 再定义一个makeFly()方法,其中让会飞的事物飞。并在main方法中调用该方法, 让飞机和鸟起飞。

    package b; public interface CanFly { public void fly(); } package b; public class FeiJi implements C ...