题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1009

显而易见的动态规划加矩阵快速幂,不过转移方程不怎么好想,dp[i][j]表示长度为i的准考证号后j位与不吉利数字的前j位相同的方案数。则:

转移方程为$dp[i][j]=\sum_{k=0}^{m-1}dp[i-1][k]*g[k][j]$

答案为:$ans=\sum_{i=0}^{m}dp[n][i]$

g[i][j]表示长度为i的后缀变成长度为j的后缀的方案数。

而g数组可以用kmp预处理出来

附上洛谷40分不用矩阵优化的代码

 1  1 #include<bits/stdc++.h>
 2  2 using namespace std;
 3  3 typedef long long ll;
 4  4 typedef unsigned long long ull;
 5  5 const int maxn = 6e6 + 10;
 6  6 ll Next[25];
 7  7 ll g[25][25];
 8  8 ll dp[maxn][25];
 9  9 char s[25];
10 10 void getN(int n) {
11 11     Next[0] = -1;
12 12     int i = 0, j = -1;
13 13     while (i < n) {
14 14         if (j == -1 || s[i] == s[j])
15 15             Next[++i] = ++j;
16 16         else
17 17             j = Next[j];
18 18     }
19 19 }
20 20 int main() {
21 21     ll n, m, mod;
22 22     scanf("%lld%lld%lld", &n, &m, &mod);
23 23     scanf("%s", s);
24 24     getN(m);
25 25     Next[0] = 0;
26 26     for (int i = 0; i < m; i++) {
27 27         for (int j = '0'; j <= '9'; j++) {
28 28             int t = i;
29 29             while (t&& s[t] != j)
30 30                 t = Next[t];
31 31             if (s[t] == j)
32 32                 t++;
33 33             g[i][t]++;
34 34         }
35 35     }
36 36     dp[0][0] = 1;
37 37     for (int i = 1; i <= n; i++) {
38 38         for (int j = 0; j < m; j++) {
39 39             for (int k = 0; k < m; k++) {
40 40                 dp[i][j] = (dp[i][j] + dp[i - 1][k] * g[k][j]) % mod;
41 41             }
42 42         }
43 43     }
44 44     ll ans = 0;
45 45     for (int i = 0; i < m; i++)
46 46         ans = (ans + dp[n][i]) % mod;
47 47     printf("%lld\n", ans);
48 48 }

View Code

以及正解

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 typedef unsigned long long ull;
 5 const int maxn = 6e6 + 10;
 6 ll Next[25];
 7 ll n, m, mod;
 8 ll dp[25][25];
 9 char s[25];
10 void getN(int n) {
11     Next[0] = -1;
12     int i = 0, j = -1;
13     while (i < n) {
14         if (j == -1 || s[i] == s[j])
15             Next[++i] = ++j;
16         else
17             j = Next[j];
18     }
19 }
20 struct matrix {
21     ll cnt[25][25];
22     matrix() { memset(cnt, 0, sizeof(cnt)); }
23     matrix operator *(const matrix a)const {
24         matrix ans;
25         for (int i = 0; i <= m; i++) {
26             for (int j = 0; j <= m; j++) {
27                 ans.cnt[i][j] = 0;
28                 for (int k = 0; k <= m; k++)
29                     ans.cnt[i][j] = (ans.cnt[i][j] + cnt[i][k] * a.cnt[k][j]) % mod;
30             }
31         }
32         return ans;
33     }
34 };
35 matrix powM(matrix a, int b) {
36     matrix ans = matrix();
37     for (int i = 0; i <= m; i++)
38         ans.cnt[i][i] = 1;
39     while (b) {
40         if (b & 1)
41             ans = ans * a;
42         a = a * a;
43         b /= 2;
44     }
45     return ans;
46 }
47 int main() {
48     matrix g, ans, dp = matrix();
49     scanf("%lld%lld%lld", &n, &m, &mod);
50     scanf("%s", s);
51     getN(m);
52     Next[0] = 0;
53     memset(g.cnt, 0, sizeof(g.cnt));
54     for (int i = 0; i < m; i++) {
55         for (int j = '0'; j <= '9'; j++) {
56             int t = i;
57             while (t&& s[t] != j)
58                 t = Next[t];
59             if (s[t] == j)
60                 t++;
61             g.cnt[i][t]++;
62         }
63     }
64     dp.cnt[0][0] = 1;
65     ans = powM(g, n);
66     ans = dp * ans;
67     ll sum = 0;
68     for (int i = 0; i < m; i++)
69         sum = (sum + ans.cnt[0][i]) % mod;
70     printf("%lld\n", sum);
71 }

View Code

转载于:https://www.cnblogs.com/sainsist/p/11126100.html

[Bzoj1009][HNOI2008]GT考试(动态规划)相关推荐

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

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

  2. BZOJ_1009_[HNOI2008]_GT考试_(动态规划+kmp+矩阵乘法优化+快速幂)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1009 字符串全部由0~9组成,给出一个串s,求一个长度为n的串,不包含s的种类有多少. 分析 ...

  3. BZOJ 1009 [HNOI2008]GT考试

    1009: [HNOI2008]GT考试 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 2154  Solved: 1327 [Submit][Sta ...

  4. bzoj 1009: [HNOI2008]GT考试(dp+kmp+矩阵快速幂)

    1009: [HNOI2008]GT考试 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 3932  Solved: 2398 [Submit][Sta ...

  5. [HNOI2008 GT考试]

    [关键字]:动态规划 矩阵乘法 [题目大意]:给定一个字符集为(0-9)的字符串T(length<=20),求长度为N的不包含T的字符串的总数. //====================== ...

  6. [HNOI2008]GT考试[矩阵快速幂+kmp优化的dp]

    解题思路:假如说我们用f[i]表示长度为i的串能组合成无不吉利数字的组合的个数的话我们无法找到f[i]和f[i+1]的关系,就是我们下一位填某个数字会不会出现不吉利串,这就和你前面的串末尾于不吉利串重 ...

  7. BZOJ 1009:[HNOI2008]GT考试

    题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=1009 大意:给一个长度不大于20的数字串,求长度为N(10^9)的所有数字串中不包含该串 ...

  8. BZOJ 1009: [HNOI2008]GT考试(kmp+dp+矩阵优化)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1009 题意: 思路: 真的是好题啊! 对于这种题目,很有可能就是dp,$f[i][j]$表示分析到第 ...

  9. [HNOI2008]GT考试

    题意 有一个长度为\(n\)\((n\le1e^9)\)只由阿拉伯数字组成的串\(A\),现在给一个长度为\(m\)\((m\le20)\)同样只由阿拉伯数字组成的串\(B\),求满足条件的\(A\) ...

  10. BZOJ[1009] [HNOI2008]GT考试

    了了已久的心结 f[i][j]表示到第i为,长度为j的后缀与不吉利数字的前缀相同,其实这个和一些期望概率的DP类似,利用a数组记录当前j在加上不同的数字之后,可以分别转移至那些状态,用KMP处理一下, ...

最新文章

  1. php视频生成指定帧图片,python3.5 cv2 获取视频特定帧生成jpg图片
  2. Linux内核访问外设I O资源的方式
  3. android pay 绑定失败,实战Apple Pay失败!Android Pay你期待吗?
  4. 美团深度学习系统的工程实践
  5. 利用计算机语言进行并行性描述,有没有一种语言可以利用大规模并行计算机?...
  6. 经典领导选举算法:Bully 算法
  7. javascript探秘-检测浏览器和操作系统
  8. Windows目录下SysWow64文件夹与System32文件夹
  9. 3种实现CSS 上下居中的方法
  10. TIA博途中通过PN耦合器实现不同网段的PLC进行PROFINET通信的具体方法
  11. modelsim/Questasim中添加xilinx ip库,并仿真成功
  12. 2018 DDoS攻击加剧,闻“D”色变的无力困境,我们要怎么办
  13. Loss和神经网络训练
  14. 计算机考试分值2017,2017计算机二级考试应试技巧
  15. 学习率和数据集规模_数据集和数据
  16. git 强制同步远端仓库
  17. BZOJ3238 后缀自动机+推公式
  18. 4G、5G中的基本时间单位Ts和Tc
  19. 2019 年第 7 周 DApp 影响力排行榜 | TokenInsight
  20. 前端程序员到底应该学什么?怎么学?从哪开始学?

热门文章

  1. linux怎么启动程序路径,linux查找启动程序的路径
  2. JSP教程第4讲笔记
  3. Java Greedy Snake, need to be updated
  4. linux强制获得锁,Linux中的两种文件锁——协同锁与强制锁
  5. 中计算正方形面积的方法_风管及管道部件设计过程中常用的计算方法
  6. attention机制的几种方法
  7. ubuntu16.04命令行模式和图形界面互相切换
  8. Caffe for Python 官方教程(翻译)
  9. CTF入门指南(Capture the flag)
  10. DeepLearning tutorial(7)深度学习框架Keras的使用-进阶