题目大意:用k种字符构建两个长度为n的字符串(每种字符有无限多个),要求对应位置字符相同的连续子串最长长度为m,问方法数。

其中k,n,m是输入,n(1<=n<=1000000000), m(1<=m<=10), k(1<=k<=26).

对题目解释更详细点儿,如下两串

123456

223466

这个的“对应位置字符相同的连续子串最长长度”是3,是字符串“234”。

解题思路,这题一看就是DP或者组合数学,但是不会组合数学,只能DP了
dp[i][j]表示前i个字符,最后j个位置相同的方法数

第三维01表示该状态是否包含了至少一个长度为m的“对应位置相同子串”

dp[i][j][0]=dp[i-1][j-1][0]*k                                                          (0<j<m)
dp[i][0][0]=sum(dp[i-1][0到m-1][0])*k*(k-1)
dp[i][j][1]=dp[i-1][j-1][1]*k                                                          (0<j<=m)
dp[i][0][1]=(sum(dp[i-1][0到m][1])+dp[i-1][m-1][0])*k*(k-1)
 
由于第一维范围过大,且只和前一个状态有关,很明显想到矩阵乘法优化递推。完整代码如下:
 #include <iostream>
#include <cstdio>
#include <cstring> using namespace std;
typedef long long ll;
const int N = ;
const ll MOD=;
struct Mat {
ll mat[N][N];
Mat()
{
memset(mat,,sizeof(mat));
}
void clear(){
memset(mat,,sizeof(mat));
}
}; ll num[N];
int n, m,K;
Mat a; void init() {
//初始化状态转移矩阵
a.clear();
for(int j=;j<m;j++)a.mat[][j]=K*(K-);
for(int i=;i<m;i++)a.mat[i][i-]=K;
for(int j=m;j<=*m;j++)a.mat[m][j]=K*(K-);
for(int i=m+;i<=*m;i++)a.mat[i][i-]=K;
a.mat[*m][m-]=K;
} Mat operator * (Mat a, Mat b) {
Mat c;
for(int i=;i<=*m;i++){
for(int j=;j<=*m;j++){
for(int k=;k<=*m;k++){
c.mat[i][j]+=b.mat[i][k]*a.mat[k][j];
c.mat[i][j]%=MOD;
}
}
}
return c;
} Mat operator ^ (Mat a, int k) {
//初状态
Mat c;
c.mat[][]=;
//快速幂
for(; k; k >>= ) {
if(k&) c = c*a;
a = a*a;
}
return c;
} int main() {
//freopen("data.in", "r", stdin);
int T;
scanf("%d",&T);
while(~scanf("%d%d%d",&n,&m,&K)) {
//初始化状态转移矩阵
init();
//矩阵快速幂,初始左矩阵不是单位矩阵,是初状态
a = a^n;
//得到最终矩阵后求答案
ll ans=;
for(int i = m; i <= *m; ++i) {
ans+=a.mat[i][];
ans%=MOD;
}
printf("%lld\n", ans);
}
return ;
}

HDU 5863

然后写这个主要是想记录下矩阵乘法的板子

#include <iostream>
#include <cstdio>
#include <cstring> using namespace std;
typedef long long ll;
const int N = ;
const long long MOD=;
struct Mat {
ll mat[N][N];
Mat()
{
memset(mat,,sizeof(mat));
}
void clear(){
memset(mat,,sizeof(mat));
}
}; ll num[N];
int n, m,K;
Mat a; void init() {
//初始化状态转移矩阵
a.clear();
for(int j=;j<m;j++)a.mat[][j]=K*(K-);
for(int i=;i<m;i++)a.mat[i][i-]=K;
for(int j=m;j<=*m;j++)a.mat[m][j]=K*(K-);
for(int i=m+;i<=*m;i++)a.mat[i][i-]=K;
a.mat[*m][m-]=K;
} Mat operator * (Mat a, Mat b) {
Mat c;
for(int i=;i<=*m;i++){
for(int j=;j<=*m;j++){
for(int k=;k<=*m;k++){
c.mat[i][j]+=b.mat[i][k]*a.mat[k][j];
c.mat[i][j]%=MOD;
}
}
}
return c;
} Mat operator ^ (Mat a, int k) {
//初状态
Mat c;
c.mat[][]=;
//快速幂
for(;k;k>>=){
if(k&)c=c*a;
a=a*a;
}
return c;
} int main() {
//freopen("data.in", "r", stdin);
//初始化状态转移矩阵
init();
//矩阵快速幂,初始左矩阵不是单位矩阵,是初状态
a = a^n;
return ;
}
 
 

HDU 5863 cjj's string game (矩阵乘法优化递推)的更多相关文章

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

    题目链接 题意 : 有种不同的字符,每种字符有无限个,要求用这k种字符构造两个长度为n的字符串a和b,使得a串和b串的最长公共部分长度恰为m,问方案数 分析 : 直觉是DP 不过当时看到 n 很大.但 ...

  2. HDU 5863 cjj's string game

    $dp$,矩阵加速. 设$dp[i][j][0]$表示:长度为$i$的两个字符串,之前还未出现过长度为$m$相同的,目前为止最后$j$个是相同的. 设$dp[i][j][1]$表示:长度为$i$的两个 ...

  3. [模板][题解][Luogu1939]矩阵乘法加速递推(详解)

    题目传送门 题目大意:计算数列a的第n项,其中: \[a[1] = a[2] = a[3] = 1\] \[a[i] = a[i-3] + a[i - 1]\] \[(n ≤ 2 \times 10^ ...

  4. BZOJ 4870: [Shoi2017]组合数问题 矩阵乘法_递推

    Code: #include <cstdio> #include <cstring> #include <algorithm> #define setIO(s) f ...

  5. [BZOJ 1009] [HNOI2008] GT考试 【AC自动机 + 矩阵乘法优化DP】

    题目链接:BZOJ - 1009 题目分析 题目要求求出不包含给定字符串的长度为 n 的字符串的数量. 既然这样,应该就是 KMP + DP ,用 f[i][j] 表示长度为 i ,匹配到模式串第 j ...

  6. [转]OpenBLAS项目与矩阵乘法优化

    课程内容 OpenBLAS项目介绍 矩阵乘法优化算法 一步步调优实现 以下为公开课完整视频,共64分钟: 以下为公开课内容的文字及 PPT 整理. 雷锋网的朋友们大家好,我是张先轶,今天主要介绍一下我 ...

  7. 【BZOJ 3326】[Scoi2013]数数 数位dp+矩阵乘法优化

    挺好的数位dp……先说一下我个人的做法:经过观察,发现这题按照以往的思路从后往前递增,不怎么好推,然后我就大胆猜想,从前往后推,发现很好推啊,维护四个变量,从开始位置到现在有了i个数 f[i]:所有数 ...

  8. bzoj4870: [Shoi2017]组合数问题(DP+矩阵乘法优化)

    为了1A我居然写了个暴力对拍... 那个式子本质上是求nk个数里选j个数,且j%k==r的方案数. 所以把组合数的递推式写出来f[i][j]=f[i-1][j]+f[i-1][(j-1+k)%k].. ...

  9. 形态形成场(矩阵乘法优化dp)

    形态形成场(矩阵乘法优化dp) 短信中将会涉及前\(k\)种大写字母,每个大写字母都有一个对应的替换式\(Si\),替换式中只会出现大写字母和数字,比如\(A→BB,B→CC0,C→123\),代表 ...

随机推荐

  1. node.js date-utils

    前端引用 <script type="text/javascript" src="date-utils.min.js"></script> ...

  2. 关于PHP中的SESSION技术

    Session是服务器端技术,服务器在运行时可以为每一个用户创建一个其独享的session文件,所以用户在访问服务器web资源时,可以把各自的数据放在各自的session中,当用于再去访问该服务器中其 ...

  3. the selection cannot be run on any server

    导入war包后运行jsp 显示: the selection cannot be run on any server 问题原因: Dynamic Web Module 的版本与server不匹配.Dy ...

  4. android黑科技系列——静态分析技术来破解Apk

    一.前言 从这篇文章开始我们开始我们的破解之路,之前的几篇文章中我们是如何讲解怎么加固我们的Apk,防止被别人破解,那么现在我们要开始破解我们的Apk,针对于之前的加密方式采用相对应的破解技术,And ...

  5. Django学习笔记----settings and database_based App demo

    原文参考docs.djangoproject.com, what can manage.py utility do? find here. 1.Database Setup 编辑settings.py ...

  6. jquey中的事件绑定

    三种方法: $(selector).live(events, data, handler);                // jQuery 1.3+ $(document).delegate(se ...

  7. SqlServer与MySql语法比较

    1.复制表(包括表结构.表数据) SqlServer: Select * into user_copy from user MySql: CREATE TABLE user_copy LIKE use ...

  8. 几个方便编程的C++特性

    前言: C++11的自动化特性给编程提供了不少方便,同时也给调试增加了很多负担,至于取舍看程序员的风格和侧重而定. auto:自动类型推断 在C++11之前,auto关键字用来指定存储期.在新标准中, ...

  9. 【从零开始】【Java】【3】改造成多模块项目

    闲聊 前几天还是太懒惰了,毕竟也是世界杯期间嘛,可以自我理解的,嘿嘿. 毕竟是从头开始,但是不一定适合所有新入门的人,所以搭框架啊.引入框架什么的,是占据最开始时间比较多的,代码层面的,可能要到靠后面 ...

  10. Kafka学习笔记(4)----Kafka的Leader Election

    1. Zookeeper的基本操作 zookeeper中的节点可以持久化/有序的两个维度分为四种类型: PERSIST:持久化无序(保存在磁盘中) PERSIST_SEQUENTIAL:持久化有序递增 ...