[Bzoj1009][HNOI2008]GT考试(动态规划)
题目链接: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分不用矩阵优化的代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 6e6 + ;
ll Next[];
ll g[][];
ll dp[maxn][];
char s[];
void getN(int n) {
Next[] = -;
int i = , j = -;
while (i < n) {
if (j == - || s[i] == s[j])
Next[++i] = ++j;
else
j = Next[j];
}
}
int main() {
ll n, m, mod;
scanf("%lld%lld%lld", &n, &m, &mod);
scanf("%s", s);
getN(m);
Next[] = ;
for (int i = ; i < m; i++) {
for (int j = ''; j <= ''; j++) {
int t = i;
while (t&& s[t] != j)
t = Next[t];
if (s[t] == j)
t++;
g[i][t]++;
}
}
dp[][] = ;
for (int i = ; i <= n; i++) {
for (int j = ; j < m; j++) {
for (int k = ; k < m; k++) {
dp[i][j] = (dp[i][j] + dp[i - ][k] * g[k][j]) % mod;
}
}
}
ll ans = ;
for (int i = ; i < m; i++)
ans = (ans + dp[n][i]) % mod;
printf("%lld\n", ans);
}
以及正解
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 6e6 + ;
ll Next[];
ll n, m, mod;
ll dp[][];
char s[];
void getN(int n) {
Next[] = -;
int i = , j = -;
while (i < n) {
if (j == - || s[i] == s[j])
Next[++i] = ++j;
else
j = Next[j];
}
}
struct matrix {
ll cnt[][];
matrix() { memset(cnt, , sizeof(cnt)); }
matrix operator *(const matrix a)const {
matrix ans;
for (int i = ; i <= m; i++) {
for (int j = ; j <= m; j++) {
ans.cnt[i][j] = ;
for (int k = ; k <= m; k++)
ans.cnt[i][j] = (ans.cnt[i][j] + cnt[i][k] * a.cnt[k][j]) % mod;
}
}
return ans;
}
};
matrix powM(matrix a, int b) {
matrix ans = matrix();
for (int i = ; i <= m; i++)
ans.cnt[i][i] = ;
while (b) {
if (b & )
ans = ans * a;
a = a * a;
b /= ;
}
return ans;
}
int main() {
matrix g, ans, dp = matrix();
scanf("%lld%lld%lld", &n, &m, &mod);
scanf("%s", s);
getN(m);
Next[] = ;
memset(g.cnt, , sizeof(g.cnt));
for (int i = ; i < m; i++) {
for (int j = ''; j <= ''; j++) {
int t = i;
while (t&& s[t] != j)
t = Next[t];
if (s[t] == j)
t++;
g.cnt[i][t]++;
}
}
dp.cnt[][] = ;
ans = powM(g, n);
ans = dp * ans;
ll sum = ;
for (int i = ; i < m; i++)
sum = (sum + ans.cnt[][i]) % mod;
printf("%lld\n", sum);
}
[Bzoj1009][HNOI2008]GT考试(动态规划)的更多相关文章
- [BZOJ1009] [HNOI2008] GT考试(KMP+dp+矩阵快速幂)
[BZOJ1009] [HNOI2008] GT考试(KMP+dp+矩阵快速幂) 题面 阿申准备报名参加GT考试,准考证号为N位数X1X2-.Xn,他不希望准考证号上出现不吉利的数字.他的不吉利数学A ...
- BZOJ1009 [HNOI2008]GT考试 矩阵
去博客园看该题解 题目 [bzoj1009][HNOI2008]GT考试 Description 阿申准备报名参加GT考试,准考证号为N位数X1X2….Xn(0<=Xi<=9),他不希望准 ...
- bzoj1009 [HNOI2008] GT考试 矩阵乘法+dp+kmp
1009: [HNOI2008]GT考试 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 4542 Solved: 2815[Submit][Statu ...
- [Bzoj1009][HNOI2008]GT考试(KMP)(矩乘优化DP)
1009: [HNOI2008]GT考试 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 4309 Solved: 2640[Submit][Statu ...
- bzoj1009: [HNOI2008]GT考试(kmp+矩阵乘法)
1009: [HNOI2008]GT考试 题目:传送门 题解: 看这第一眼是不是瞬间想起组合数学??? 没错...这样想你就GG了! 其实这是一道稍有隐藏的矩阵乘法,好题! 首先我们可以简化一下题意: ...
- [bzoj1009](HNOI2008)GT考试 (kmp+矩阵快速幂加速递推)
Description 阿 申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字.他的不吉利数学 A1A2...Am(0&l ...
- [bzoj1009][HNOI2008]GT考试
Description 阿申准备报名参加考试,准考证号为位数,他不希望准考证号上出现不吉利的数字. 他的不吉利数学有位,不出现是指中没有恰好一段等于. 可以为. Input 第一行输入.接下来一行输入 ...
- [BZOJ1009] [HNOI2008] GT考试 (KMP & dp & 矩阵乘法)
Description 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字. 他的不吉利数学A1A2...Am(0< ...
- bzoj1009: [HNOI2008]GT考试 ac自动机+矩阵快速幂
https://www.lydsy.com/JudgeOnline/problem.php?id=1009 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9 ...
随机推荐
- vue.js(18)--父组件向子组件传值
子组件是不能直接使用父组件中数据的,需要进行属性绑定(v-bind:自定义属性名=“msg”),绑定后需要在子组件中使用props[‘自定义属性名’]数组来定义父组件的自定义名称. props数组中的 ...
- 没有找到<context:component-scan base-package="">标签
<?xml version="1.0" encoding="UTF-8"?> <!-- 指定Spring配置文件的Schema信息 --> ...
- python if-else替代三元表达式
python中判断一个数是否是偶数的常规代码: def _compare(data): if data % 2 == 0: return True else: return False # 调用偶数判 ...
- TensorFlow 安装及使用
安装 (1)安装包安装:pip install tensorflow==1.14 -i https://pypi.douban.com/simple virtualenv -p /usr/bin/py ...
- 树——binary-tree-postorder-traversal(树的后序遍历)
问题: Given a binary tree, return the postorder traversal of its nodes' values. For example: Given bin ...
- poj 2187 Beauty Contest(平面最远点)
Beauty Contest Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 24431 Accepted: 7459 D ...
- shell 数组中 @ 跟 * 的区别
关于在shell脚本中数组变量中 “*”跟 “@” 区别 “*”当变量加上“” 会当成一串字符串处理. “@”变量加上“” 依然当做数组处理. 在没有加上“” 的情况下 效果是等效的. #!/bin/ ...
- nginx安装配置_runoob_阅读笔记_20190917
Nginx 安装配置_runoob菜鸟教程 Nginx 安装配置 Nginx("engine x")是一款是由俄罗斯的程序设计师Igor Sysoev所开发高性能的 Web和 反向 ...
- Springboot aop使用
package com.jxd.Boot.aspect; import org.aspectj.lang.JoinPoint;import org.aspectj.lang.Signature;imp ...
- Linux和VMware
1.1 Linux操作系统简介 是一个基于POSIX和UNIX的多用户.多任务.支持多线程和多CPU的操作系统.它能运行主要的UNIX工具软件.应用程序和网络协议.它支持32位和64位硬件.Lin ...