[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个点, ...
随机推荐
- 封装List集合一个批量导入数据库的工具类
public class CommonDal { #region 数据导入相关 /// <summary> /// 批量导入数据 /// </summary> /// < ...
- WeTest功能优化第1期:截图960px,云真机映射功能了解
第1期功能优化目录 [全线产品测试截图优化]安卓机型测试截图分辨率上升至960px [云真机新增Android 9]最新安卓系统,等你pick [云真机新增键盘映射功能]电脑键盘码字,云真机同步显示 ...
- Objective-C 构造方法 分类 类的深入研究
构造方法 1.对象创建的原理 new的拆分两部曲 Person *p = [Person alloc]; 分配内存(+alloc) Person *p = [p init]; 初始化(-init) 合 ...
- 小程序button 去边框
/*使用 button::after{ border: none; } 来去除边框*/.free-btn-bordernone{ background: none !important; color: ...
- JVM学习--jvm监控和故障处理工具
java虚拟机性能监控常用命令 Sun JDK监控和故障处理命令有jps.jstat.jinfo.jmap.jhat.jstack . 1.jps jps:JVM Process Status Too ...
- 关于@media不生效的问题和meta总结
1:之前做的是两套页面.现在改成响应式布局.发现加上 @media only screen and (max-width: 500px) { .gridmenu { width:1 ...
- 聊一聊session
最近从上家公司离职了,到了一家新公司,这几天一直在了解他们的项目,所以我自己的那个小项目也暂时搁浅了.. 今天差不多把他们的项目了解了,来院子写写我在这里边遇到的问题,影响最深刻的是seesion的. ...
- Document对象内容集合
document 文挡对象 - JavaScript脚本语言描述———————————————————————注:页面上元素name属性和JavaScript引用的名称必须一致包括大小写否则会提示你一 ...
- [C++] Variables and Basic Types
Getting Started compile C++ program source $ g++ -o prog grog1.cc run C++ program $ ./prog The libra ...
- Line belt(三分镶嵌)
In a two-dimensional plane there are two line belts, there are two segments AB and CD, lxhgww's spee ...