记dp[i]为长度i且符合题意的方案数,dp[n]就是解

符合方案的是不含fmf和fff子串的字符串

考虑如何从前面几项递推出后面第i项

(★表示存在生成的非法方案)←其实没啥用处

i=1时

m③ f③

i=2时

mm② mf② fm★② ff★②

i=3时

mmm mmf mfm★ mff★ fmm ffm★

i=4时

mmmm① mmmf① mmfm★① mmff★① mfmm① mffm★① fmmm① fmmf① ffmm①

i=5时

mmmmm① mmmmf② mmmfm① mmmff③ mmfmm① mmffm① mfmmm① mfmmf② mffmm① fmmmm① fmmmf② fmmfm① fmmff③ ffmmm① ffmmf②

i=5时,考虑第i-1项,其中所有方案接m都可以转移①

考虑第i-2项,只可以接_f形式,由★可得出无论是mf还是ff都有非法方案存在的结论,无法转移

考虑第i-3项,可以接__f形式 mmf可以②,mff非法,f_f非法

考虑第i-4项,只剩下mmff形式③

所有生成的第五项的串全部转移完毕,得到dp(n)=dp(n-1)+dp(n-3)+dp(n-4)

/*H E A D*/
int MOD = 9973;
inline ll mod(ll a){return a%MOD;}
struct Matrix{
ll mt[22][22],r,c;
void init(int rr,int cc,bool flag=0){
r=rr;c=cc;
memset(mt,0,sizeof mt);
if(flag) rep(i,1,r) mt[i][i]=1;
}
Matrix operator * (const Matrix &rhs)const{
Matrix ans; ans.init(r,rhs.c);
rep(i,1,r){
rep(j,1,rhs.c){
int t=max(r,rhs.c);
rep(k,1,t){
ans.mt[i][j]+=mod(mt[i][k]*rhs.mt[k][j]);
ans.mt[i][j]=mod(ans.mt[i][j]);
}
}
}
return ans;
}
};
Matrix fpw(Matrix A,int n){
Matrix ans;ans.init(A.r,A.c,1);
while(n){
if(n&1) ans=ans*A;
n>>=1;
A=A*A;
}
return ans;
}
int bas[5][5]={
{0,0,0,0,0},
{0,1,0,1,1},
{0,1,0,0,0},
{0,0,1,0,0},
{0,0,0,1,0},
};
int bas2[5]={0,9,6,4,2};
int main(){
int n,m;
Matrix A;A.init(4,4);
rep(i,1,4) rep(j,1,4) A.mt[i][j]=bas[i][j];
Matrix b; b.init(4,1);
rep(i,1,4) b.mt[i][1]=bas2[i];
while(cin>>n>>m){
MOD=m;
if(n<=3){
println(b.mt[5-n][1]%MOD);
continue;
}
Matrix res=fpw(A,n-4); res=res*b;
ll ans=mod(res.mt[1][1]+m);
println(ans);
}
return 0;
}

解法二:

很显然不断拼接枚举简直累死人,干嘛不直接把三位的子串全部递推出来

注意fmf和fff递推时强制设0表示非法方案

保险起见还是设递推项为第五项开始

时间复杂度较高,不过依然能AC

/*H E A D*/
int MOD = 9973;
inline ll read(){
ll x=0,f=1;register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
inline ll mod(ll a){return a%MOD;}
struct Matrix{
ll mt[22][22],r,c;
void init(int rr,int cc,bool flag=0){
r=rr;c=cc;
memset(mt,0,sizeof mt);
if(flag) rep(i,1,r) mt[i][i]=1;
}
Matrix operator * (const Matrix &rhs)const{
Matrix ans; ans.init(r,rhs.c);
rep(i,1,r){
rep(j,1,rhs.c){
int t=max(r,rhs.c);
rep(k,1,t){
ans.mt[i][j]+=mod(mt[i][k]*rhs.mt[k][j]);
ans.mt[i][j]=mod(ans.mt[i][j]);
}
}
}
return ans;
}
};
Matrix fpw(Matrix A,int n){
Matrix ans;ans.init(A.r,A.c,1);
while(n){
if(n&1) ans=ans*A;
n>>=1;
A=A*A;
}
return ans;
}
// 4 7 -> 9->O fff_(m|f) fmf_(m|f) fff fmf
//dp[1][i]:fff dp[1][i+1]=0dp[1][i]+0dp[2][i] 0
//dp[2][i]:mff dp[2][i+1]=dp[3][i]+dp[5][i] 2
//dp[3][i]:fmf dp[3][i+1]=0dp[4][i]+0dp[6][i] 0
//dp[4][i]:ffm dp[4][i+1]=dp[1][i]+dp[2][i] 1
//dp[5][i]:mmf dp[5][i+1]=dp[7][i]+dp[8][i] 4
//dp[6][i]:mfm dp[6][i+1]=dp[3][i]+dp[5][i] 2
//dp[7][i]:fmm dp[7][i+1]=dp[4][i]+dp[6][i] 2
//dp[8][i]:mmm dp[8][i+1]=dp[7][i]+dp[8][i] 4
int bas[9][9]={
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0},
{0,0,0,1,0,1,0,0,0},
{0,0,0,0,0,0,0,0,0},
{0,1,1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,1,1},
{0,0,0,1,0,1,0,0,0},
{0,0,0,0,1,0,1,0,0},
{0,0,0,0,0,0,0,1,1},
};
int bas2[9]={0,0,2,0,1,4,2,2,4};
int main(){
int n,m;
Matrix A;A.init(8,8);
rep(i,1,8) rep(j,1,8) A.mt[i][j]=bas[i][j];
Matrix b; b.init(8,1);
rep(i,1,8) b.mt[i][1]=bas2[i];
while(cin>>n>>m){
MOD=m;
if(n<=4){
switch(n){
case 0 :println(0%MOD);break;
case 1 :println(2%MOD);break;
case 2 :println(4%MOD);break;
case 3 :println(6%MOD);break;
case 4 :println(9%MOD);break;
}
continue;
}
Matrix res=fpw(A,n-5); res=res*b;
ll ans=0;
// rep(i,1,8) cout<<res.mt[i][1]<<" ";cout<<endl;
rep(i,1,8) ans=mod(ans+res.mt[i][1]+m);
println(ans);
}
return 0;
}

HDU - 2604 矩阵快速幂 字符串递推 两种解法的更多相关文章

  1. HDU 1757 矩阵快速幂加速递推

    题意: 已知: 当x<10时:f(x)=x 否则:f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + --+ a9 * f(x-10); 求:f(x ...

  2. HDU 5950 - Recursive sequence - [矩阵快速幂加速递推][2016ACM/ICPC亚洲区沈阳站 Problem C]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5950 Farmer John likes to play mathematics games with ...

  3. CH 3401 - 石头游戏 - [矩阵快速幂加速递推]

    题目链接:传送门 描述石头游戏在一个 $n$ 行 $m$ 列 ($1 \le n,m \le 8$) 的网格上进行,每个格子对应一种操作序列,操作序列至多有 $10$ 种,分别用 $0 \sim 9$ ...

  4. CH3401 石头游戏(矩阵快速幂加速递推)

    题目链接:传送门 题目: 石头游戏 0x30「数学知识」例题 描述 石头游戏在一个 n 行 m 列 (≤n,m≤) 的网格上进行,每个格子对应一种操作序列,操作序列至多有10种,分别用0~9这10个数 ...

  5. HDU5950 Recursive sequence (矩阵快速幂加速递推) (2016ACM/ICPC亚洲赛区沈阳站 Problem C)

    题目链接:传送门 题目: Recursive sequence Time Limit: / MS (Java/Others) Memory Limit: / K (Java/Others) Total ...

  6. AcWing 226. 233矩阵 (矩阵快速幂+线性递推)打卡

    题目:https://www.acwing.com/problem/content/228/ 题意:有一个二维矩阵,这里只给你第一行和第一列,要你求出f[n][m],关系式有    1,  f[0][ ...

  7. BZOJ4547 Hdu5171 小奇的集合 【矩阵快速幂优化递推】

    BZOJ4547 Hdu5171 小奇的集合 Description 有一个大小为n的可重集S,小奇每次操作可以加入一个数a+b(a,b均属于S),求k次操作后它可获得的S的和的最大值.(数据保证这个 ...

  8. [bzoj1009](HNOI2008)GT考试 (kmp+矩阵快速幂加速递推)

    Description 阿 申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字.他的不吉利数学 A1A2...Am(0&l ...

  9. [bzoj1008](HNOI2008)越狱(矩阵快速幂加速递推)

    Description 监狱有连续编号为1...N的N个房间,每个房间关押一个犯人,有M种宗教,每个犯人可能信仰其中一种.如果相邻房间的犯人的宗教相同,就可能发生越狱,求有多少种状态可能发生越狱 In ...

随机推荐

  1. 在C语言中如何嵌入python脚本

    最近在写配置文件时,需要使用python脚本,但脚本是一个监控作用,需要它一直驻留在linux中运行,想起C语言中能够使用deamon函数来保留一个程序一直运行,于是想到写一个deamon,并在其中嵌 ...

  2. Asp.NET中把DataTable导出为Excel ,中文有乱码现象解决办法

    //DataTable为要导出的数据表   DataGrid dg = new DataGrid();                dg.DataSource = DataTable;        ...

  3. [GO]冒泡排序的原理和代码实现

    冒泡排序的原理:对于一个数组里所有的元素进行两两比较,发生大于则变换数组下标则为升序排序,发生小于则变换数据下标的则为降序排序 比如给定的数组为[1, -2, 3, -4],对于我们的需求,两两比较后 ...

  4. 20169219 SQL注入实验报告

    实验介绍 SQL注入技术是利用web应用程序和数据库服务器之间的接口来篡改网站内容的攻击技术.通过把SQL命令插入到Web表单提交框.输入域名框或页面请求框中,最终欺骗服务器执行恶意的SQL命令. 在 ...

  5. 常用Linux命令:netstat

    一.netstat:显示各种网络相关信息 1.命令格式 netstat [参数] 2.常用参数 -a   :(all)显示所有选项,默认不现实LISTEN相关 -t    :(tcp)仅显示tcp相关 ...

  6. POJ2442 Sequence(堆的骚操作)

    Description Given m sequences, each contains n non-negative integer. Now we may select one number fr ...

  7. MongoDB整理笔记の安全访问

    MongoDB安全访问将从以下三个方面得到控制!   1.绑定IP内网地址访问MongoDB服务     2.设置监听端口     3.使用用户名和密码 绑定IP内网地址访问MongoDB服务 Mon ...

  8. [转]FreeMarker使用

    copy自http://demojava.iteye.com/blog/800204 以下内容全部是网上收集: FreeMarker的模板文件并不比HTML页面复杂多少,FreeMarker模板文件主 ...

  9. angular HTML属性绑定

  10. 从头开始学eShopOnContainers——Visual Studio 2017环境配置

    一.安装和配置Docker环境 1.安装Docker CE for Windows 从官方网站下载并安装,https://docs.docker.com/docker-for-windows/inst ...