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

GT考试准考证号生成算法
探讨了在GT考试中,如何生成不包含特定不吉利数字的准考证号的算法。利用KMP算法预处理模式串,通过动态规划计算满足条件的准考证号数量,并使用矩阵快速幂进行高效计算。

描述


http://www.lydsy.com/JudgeOnline/problem.php?id=1009

字符串全部由0~9组成,给出一个串s,求一个长度为n的串,不包含s的种类有多少.

 

分析


第一眼以为是组合.然后更滑稽的是用错误的方法手算样例居然算出来是对的...我数学是有多差...

题解也是看了好半天,有点难理解.

感觉PoPoQQQ神犇讲得还是比较清楚的.传送门:http://blog.csdn.net/popoqqq/article/details/40188173

我们用dp[i][j]表示 : 长度为i的串, 其长度为j的后缀 与 s长度为j的前缀 完全匹配的种类数.

这样的话最后的答案就是ans=sigma{dp[n][i]}(0<=i<m).

这里还有一个二维的a数组,就这个比较难解释...

dp[i][y]可以由dp[i-1][x]转移而来,那么匹配的s的前缀由长度x变成了长度y,a[x][y]表示的就是在结尾添加一个字符后,匹配长度从x变成y,这样的字符有多少种.

那么 dp[i][y]=sigma{dp[i-1][x]*a[x][y]}.

这个可以用矩阵乘法算.

那么a数组怎么求呢?用kmp.

a[x][y]表示的是前缀匹配长度由x变成了y的种类数,那么从每一位i开始匹配,如果匹配到了j,那么a[i][j+1]++(数组从0开始,第i位之前匹配了i个,匹配到第j位,应该是j+1个).

 

p.s.我好菜呀...

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int maxn=100+5;
 5 int n,m,p,ans;
 6 char str[maxn];
 7 int f[maxn];
 8 
 9 struct matrix{
10     int x[25][25];
11     matrix(){ memset(x,0,sizeof x); }
12     int * operator [] (int id){ return x[id]; }
13 }dp,a;
14 void operator *= (matrix &x,matrix &y){
15     matrix z;
16     for(int i=0;i<m;i++)for(int j=0;j<m;j++)for(int k=0;k<m;k++)
17         z[i][j]+=x[i][k]*y[k][j], z[i][j]%=p;
18     x=z;
19 }
20 void kmp(){
21     for(int i=1;i<m;i++){
22         int j=f[i];
23         while(j&&str[i]!=str[j]) j=f[j];
24         f[i+1]=str[i]==str[j]?j+1:0;
25     }
26     for(int i=0;i<m;i++)for(char k='0';k<='9';k++){
27         int j=i;
28         while(j&&k!=str[j]) j=f[j];
29         if(k==str[j]) a[i][j+1]++;
30         else a[i][0]++;
31     }
32 }
33 void quick_power(int y){
34     for(;y;a*=a,y>>=1) if(y&1) dp*=a;
35 }
36 int main(){
37     scanf("%d%d%d",&n,&m,&p);
38     scanf("%s",str);
39     kmp();
40     dp[0][0]=1;
41     quick_power(n);
42     for(int i=0;i<m;i++) ans+=dp[0][i], ans%=p;
43     printf("%d\n",ans);
44     return 0;
45 }
View Code

 

1009: [HNOI2008]GT考试

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 2815  Solved: 1738
[Submit][Status][Discuss]

Description

  阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字。
他的不吉利数学A1A2...Am(0<=Ai<=9)有M位,不出现是指X1X2...Xn中没有恰好一段等于A1A2...Am. A1和X1可以为
0

Input

  第一行输入N,M,K.接下来一行输入M位的数。 N<=10^9,M<=20,K<=1000

Output

  阿申想知道不出现不吉利数字的号码有多少种,输出模K取余的结果.

Sample Input

4 3 100
111

Sample Output

81

HINT

Source

转载于:https://www.cnblogs.com/Sunnie69/p/5554726.html

【源码免费下载链接】:https://renmaiwang.cn/s/6gqq2 C#语言开发的简单学生信息管理系统知识点总结基于C#语言设计并实现了一个简单的学生信息管理系统。该系统旨在为用户提供一个高效便捷的学生信息管理工具。其主要功能包括:用户登录、添加和查询学生数据等核心操作。 系统运行环境要求为Windows操作系统,开发环境采用Visual Studio进行项目配置与代码编译。系统架构主要包含以下几个部分: 1. 登录界面设计:提供友好的登录界面,支持用户名和密码验证。 2. 数据库连接功能:通过ADO.NET技术实现对本地数据库的访问,并支持基本的数据操作。 3. 数据显示与编辑:使用DataGridView控件展示并管理学生数据信息。 系统开发过程主要包括以下几个步骤: 1. 登录界面功能模块设计:基于C#语言构建登录功能的类和事件处理机制。 2. 数据库操作实现:通过编写SQL语句完成学生数据的增删改查功能。 3. 数据显示与编辑实现:结合DataSet绑定技术,将数据库数据展示在DataGridView控件上。 系统开发过程中采用的主要技术和方法包括: 1. C#语言:作为主要编程语言,C#提供了丰富的语法结构和强大的类库支持。 2. Windows Forms界面设计框架:为系统提供友好的人机交互界面。 3. ADO.NET技术:实现对数据库的高效访问与数据操作。 本系统的开发成果表明,基于C#语言的简单学生信息管理系统能够满足基本的学生信息管理需求,并且具有良好的扩展性和维护性。该系统在教育信息化领域具有一定的应用价值和推广潜力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值