题目大意:用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. 测试数据准备中用到到csv写文件知识点

    对于大数据测试中,有时需要自己去准备一些数据,用csvreader来写一个比较大的文件就比较方便,下面我就直接贴示例代码了: package com.acxm.amysu.test;import co ...

  2. guice基本使用,常用的绑定方式(四)

    guice在moudle中提供了良好的绑定方法. 它提供了普通的绑定,自定义注解绑定,按名称绑定等. 下面直接看代码: package com.ming.user.test; import com.g ...

  3. 使用Micrisoft.net设计方案 第二章组织模式

    第二章组织模式 模式不仅依赖于它所包含的更小模式,同时也依赖包含它的更大的模式.它是描述复杂软件的系统方法. 本章的目标是让我们了解以下问题: 1.如何标识模式与模式的关系 2.如何把模式组织成模式集 ...

  4. P1410 子序列

    题目描述 给定一个长度为N(N为偶数)的序列,问能否将其划分为两个长度为N/2的严格递增子序列, 输入输出格式 输入格式: 若干行,每行表示一组数据.对于每组数据,首先输入一个整数N,表示序列的长度. ...

  5. css3伸缩布局中justify-content详解

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. The AJAX response: XML, HTML, or JSON?

    shared from: http://www.quirksmode.org/blog/archives/2005/12/the_ajax_respon.html 1. 返回XML文档 对返回的XML ...

  7. Warning:关于_CRT_SECURE_NO_WARNINGS

    Warning 1 warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s in ...

  8. (转)RabbitMQ学习之spring整合发送异步消息(注解实现)

    http://blog.csdn.net/zhu_tianwei/article/details/40919249 实现使用Exchange类型为DirectExchange. routingkey的 ...

  9. Amaze UI的一点总结

    做一个微信公众号内的网页的时候,用到了Amaze UI,也称妹子UI. 官网上宣称,Amaze UI中国首个开源 HTML5 跨屏前端框架,用下来的感觉是比较类似于bootstrap,都是移动端优先. ...

  10. <td colspan="6"></td>代表这个td占6个td的位置

    <td colspan="6"><span class="order-time">2017-10-11 14:55:23</spa ...