[HNOI2008]GT考试 矩阵优化DP
题解:
一开始看觉得很难,理解了之后其实还挺容易的。
首先我们考虑朴素DP:
令f[i][j]表示长串到了第i项, 与不吉利数字(模式串)匹配到了第j项的方案。
显然ans = f[n][0] + f[n][1] + …… + f[n][m-1];
可以肉眼看出f[1][0] = 9, f[1][1] = 1;
于是我们考虑如何转移。
首先我们观察到,f[i-1][j]如果要给f[i][k]做贡献,那么就要使得匹配到j位变成匹配到k位。
我们设g[j][k]表示原本是匹配到j位,加入一个新数字后变成匹配到k位的方案数。这里的匹配到x位的x是指匹配到模式串的第x位。
那么我们有转移方程:$f[i][j] = \sum_{i=0}^{m-1}f[i-1][k]*g[k][j]$
那么如何求解g[i][j]呢?
可以考虑KMP。但是由于数据比较小,所以这里就直接用暴力了。
首先我们枚举i表示当前已经匹配到了第i位(i可以为0)
然后我们枚举新加进来的数
再我们再枚举可能会匹配 l 位,从高位开始枚举,
然后暴力检验看是不是可以刚好匹配到 l 位,注意要从后面开始匹配,如果没解释清楚,看代码就知道了。
如果可以刚好匹配到 l 位,那么我们就++g[i][l]并break
然后我们考虑优化:
观察转移方程$f[i][k] = \sum_{i=0}^{m-1}f[i-1][j]*g[j][k]$.
emmmm,..与矩阵相乘完美吻合。。。。
所以用矩阵加速一下就好啦
#include<bits/stdc++.h>
using namespace std;
#define R register int
#define AC 23
int n, m, p, ans;
char s[AC], tmp[AC];
struct matrix{
int s[AC][AC];
}f, g, box; void pre()
{
scanf("%d%d%d", &n, &m, &p);
scanf("%s", s + );
if(n == )
{
if(m == ) ans = ;
else ans = ;
ans %= p;
printf("%d\n", ans);
exit();
}
//g.s[0][1] = 1, g.s[0][0] = 9;//因为g是匹配数,所以行也可能是0
for(R i = ; i < m ; i++)//枚举已经匹配到了哪一位
{
tmp[i] = s[i];
for(R j = ; j <= ; j++)//枚举下一位是什么
{
tmp[i + ] = j + '';
int t, k = ;
for(R l = i + ; l >= ; l--)//枚举最多可以匹配几位
{
t = l, k = i + ;
while(s[t] == tmp[k] && t) --t, --k;
if(!t)
{
if(l != m) ++g.s[i][l];
break;
} }
}
}
} void build()
{
f.s[][] = , f.s[][] = ;
} void cal1()
{
for(R j = ; j < m; j++)//枚举是第一行的第几列,注意0也是合法的
{
box.s[][j] = ;
for(R l = ; l < m; l++)//枚举f的对应行和g的对应列
box.s[][j] += f.s[][l] * g.s[l][j];
box.s[][j] %= p;
}
f = box;
} void cal2()
{
for(R i = ; i < m; i++)
for(R j = ; j < m; j++)
{
box.s[i][j] = ;
for(R l = ; l < m; l++)
box.s[i][j] += g.s[i][l] * g.s[l][j];
box.s[i][j] %= p;
}
g = box;
} void qpow(int have)
{
while(have)
{
if(have & ) cal1();
cal2();
have >>= ;
}
} void work()
{
for(R i = ; i < m; i++) ans += f.s[][i];
ans %= p;
printf("%d\n", ans);
} int main()
{
freopen("in.in", "r", stdin);
pre();
build();
qpow(n - );
work();
fclose(stdin);
return ;
}
[HNOI2008]GT考试 矩阵优化DP的更多相关文章
- bzoj1009 [HNOI2008] GT考试 矩阵乘法+dp+kmp
1009: [HNOI2008]GT考试 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 4542 Solved: 2815[Submit][Statu ...
- 矩阵优化dp
链接:https://www.luogu.org/problemnew/show/P1939 题解: 矩阵优化dp模板题 搞清楚矩阵是怎么乘的构造一下矩阵就很简单了 代码: #include < ...
- bzoj 3120 矩阵优化DP
我的第一道需要程序建矩阵的矩阵优化DP. 题目可以将不同的p分开处理. 对于p==0 || p==1 直接是0或1 对于p>1,就要DP了.这里以p==3为例: 设dp[i][s1][s2][r ...
- HDU - 2294: Pendant(矩阵优化DP&前缀和)
On Saint Valentine's Day, Alex imagined to present a special pendant to his girl friend made by K ki ...
- [六省联考2017]组合数问题 (矩阵优化$dp$)
题目链接 Solution 矩阵优化 \(dp\). 题中给出的式子的意思就是: 求 nk 个物品中选出 mod k 为 r 的个数的物品的方案数. 考虑朴素 \(dp\) ,定义状态 \(f[i][ ...
- bzoj 1009 [HNOI2008]GT考试——kmp+矩阵优化dp
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1009 首先想到 确保模式串不出现 就是 确保每个位置的后缀不是该模式串. 为了dp,需要记录 ...
- 洛谷P3193 GT考试 kmp+矩阵优化dp
题意 求\(N\)位数字序列(可以有前导0)中不出现某\(M\)位子串的个数,模\(K\). \(N<=10^9,M<=20,K<=1000\) 分析 设\(dp[i][j]\)表示 ...
- BZOJ1009 [HNOI2008]GT考试 矩阵
去博客园看该题解 题目 [bzoj1009][HNOI2008]GT考试 Description 阿申准备报名参加GT考试,准考证号为N位数X1X2….Xn(0<=Xi<=9),他不希望准 ...
- [Sdoi2017]序列计数 矩阵优化dp
题目 https://www.lydsy.com/JudgeOnline/problem.php?id=4818 思路 先考虑没有质数限制 dp是在同余系下的,所以\(f[i][j]\)表示前i个点, ...
随机推荐
- SpringCloud Eureka 服务注册与服务发现
一.Eureka简介 spring Cloud Netflix技术栈中,Eureka作为服务注册中心对整个微服务架构起着最核心的整合作用.有了服务发现与注册,你就不需要整天改服务调用的配置文件了,你只 ...
- APP产品设计流程图
产品设计流程(toB) 工作有半个月了,遇到了很多问题,也在不断学习和充实自己,让自己的工作变得更加清晰和流程化,所以整理了这么个设计流程. 收集整理一切有用或则以后可能会用的文档. 从文档里面提炼用 ...
- 「LeetCode」0001-Two Sum(Ruby)
题意与分析 题意直接给出来了:给定一个数,返回数组中和为该数(下为\(x\))的两个数的下标. 这里有一个显然的\(O(n)\)的实现:建立一个hash表,每次读入数(记作\(p\))的时候查询has ...
- python基础之变量和简单数据类型
1.1 变量的命名和使用规范 变量名可以包含数字.字母.下划线,但是不能以数字开头. 变量名不能包含空格,可使用下划线来分割其中的单词. 不要将Python关键字和函数名用作变量名. 变量名应既简短又 ...
- myeclipse tomcat部署按钮点击没反应
进入workspace目录,删除.metadata\.plugins\org.eclipse.core.runtime\.settings\com.genuitec.eclipse.ast.deplo ...
- 使用jenkins构建一个自由风格的项目
一.创建一个freestyle风格的构建项目 二.输入任务名称和选择任务类型 三.配置项目 3.1:选择代码托管 3.2:到gitlab上去配置deploy key 3.3:到jenkins服务器去生 ...
- PyCharm 2018 最新激活方式总结(最新最全最有效)!!!
PyCharm 2018 最新激活方式总结(最新最全最有效!!!) pycharm2018 是目前python编程的主要应用工具,具有非常广泛的应用,不过对于它的破解一直比较麻烦,这里我为大家提供了三 ...
- 初学Direct X (2)
初学Direct X (2) 这一次要学习如何现实位图,尽管看过对双缓冲机制还有很多疑问,但是这并不阻碍我对他的入门了解 Direct3D提供了一个双重/后台缓冲区,在调用CreateDevice之时 ...
- 小组ITalk网站开发中使用到的一些技巧
----->Display属性和Visibility属性:一个清除内容和框体,另一个只清除内容而保留窗体: $('#abc').css({ 'font-size' : '12px', '-web ...
- python学习笔记04 --------------基本运算符
1.算数运算 + 加 - 减 * 乘 / 除 % 取模(先做除法,然后返回余数) ** 乘方(幂运算) // 取整(相除,然后返回商的整数部分) 2.比较运算(返回布尔值) == ...