SPOJ 1676 矩阵乘法+DP
题意:
给定N (1 ≤ N ≤ 10)个长度不超过6的单词,求由大写字母组成长度为L的包含至少一个给定单词的字符串有多少种,答案 mod 10007,(1 ≤ L ≤ 10^6)。
题解:
这个题最早是在一个关于trie图的论文中看到了,最近jzh又讲到了这个题,于是就把它做了~
大致有两种做法,两种方法都需要矩阵乘法加速
1、trie图中的dp
2、直接人工减少转移数量
具体做法点击这里
大致思路就是将不可能构成单词的前缀合成一类,然后胡搞就行了。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <string> 5 #include <cstdlib> 6 #include <algorithm> 7 #include <map> 8 9 #define N 60 10 #define SIZE 70 11 #define mod 10007 12 13 using namespace std; 14 15 map<string,int> mp; 16 17 int n,cnt,res,m; 18 string str[N],prefix[SIZE]; 19 20 struct MT 21 { 22 int x,y; 23 int mt[SIZE][SIZE]; 24 }zy,ans; 25 26 inline MT operator *(MT a,MT b) 27 { 28 MT c; memset(c.mt,0,sizeof c.mt); 29 c.x=a.x; c.y=b.y; 30 for(int i=1;i<=c.x;i++) 31 for(int j=1;j<=c.y;j++) 32 for(int k=1;k<=a.y;k++) 33 { 34 c.mt[i][j]+=a.mt[i][k]*b.mt[k][j]; 35 if(c.mt[i][j]>=mod) c.mt[i][j]%=mod; 36 } 37 return c; 38 } 39 40 inline void read() 41 { 42 mp.clear(); 43 for(int i=1;i<=n;i++) 44 { 45 cin>>str[i]; 46 mp[str[i]]=520; 47 } 48 } 49 50 inline bool check(string x)//检查x是否是合法的前缀 51 { 52 string::size_type pos; 53 for(int i=1;i<=n;i++) 54 { 55 pos=x.find(str[i]); 56 if(pos!=x.npos) return false; 57 } 58 return true; 59 } 60 61 inline void get_det() 62 { 63 memset(zy.mt,0,sizeof zy.mt); 64 cnt=0; 65 for(int i=1;i<=n;i++) 66 { 67 string tmp; 68 for(int j=0;j<str[i].length();j++) 69 { 70 tmp.push_back(str[i][j]); 71 if(check(tmp)&&mp[tmp]==0) 72 { 73 mp[tmp]=++cnt;//前缀字符串的映射 74 prefix[cnt]=tmp;//前缀字符串 75 } 76 } 77 } 78 zy.x=zy.y=cnt+1; 79 80 string tmp; 81 for(int i=1;i<=cnt;i++) 82 for(int j=0;j<26;j++) 83 { 84 tmp=prefix[i]; tmp.push_back(j+'A'); 85 for(int k=tmp.length();k>=0;k--) 86 { 87 if(k==0) 88 { 89 zy.mt[cnt+1][mp[prefix[i]]]++;//不存在后缀是已知的前缀 90 break; 91 } 92 else 93 { 94 string tp; 95 for(int p=tmp.length()-k;p<tmp.length();p++) 96 tp.push_back(tmp[p]); 97 if(mp[tp]==520) break;//出现单词,不合法 98 else if(mp[tp]!=0) {zy.mt[mp[tp]][mp[prefix[i]]]++;break;}//存在最大的后缀是已知的前缀 99 } 100 } 101 } 102 for(int i=0;i<26;i++) 103 { 104 string sy; 105 sy.push_back(i+'A'); 106 if(mp[sy]==0) zy.mt[cnt+1][cnt+1]++; 107 else if(mp[sy]==520) continue; 108 else zy.mt[mp[sy]][cnt+1]++; 109 } 110 111 ans.x=cnt+1; ans.y=1; 112 memset(ans.mt,0,sizeof ans.mt); 113 ans.mt[cnt+1][1]=1; 114 } 115 116 inline int qs(int a,int b) 117 { 118 int res=1; 119 while(b) 120 { 121 if(b&1) res=(res*a)%mod; 122 a=(a*a)%mod; 123 b>>=1; 124 } 125 return res; 126 } 127 128 inline void go() 129 { 130 get_det(); 131 res=qs(26,m); 132 while(m) 133 { 134 if(m&1) ans=zy*ans; 135 zy=zy*zy; 136 m>>=1; 137 } 138 139 int tmp=0; 140 for(int i=1;i<=cnt+1;i++) tmp=(tmp+ans.mt[i][1])%mod; 141 res-=tmp; 142 printf("%d\n",(res+mod)%mod); 143 } 144 145 int main() 146 { 147 while(scanf("%d%d",&n,&m)!=EOF) read(),go(); 148 return 0; 149 }
转载于:https://www.cnblogs.com/proverbs/archive/2013/02/17/2914168.html
SPOJ 1676 矩阵乘法+DP相关推荐
- 【BZOJ2326】【HNOI2011】数学作业 [矩阵乘法][DP]
数学作业 Time Limit: 10 Sec Memory Limit: 128 MB [Submit][Status][Discuss] Description Input 输入文件只有一行为用 ...
- 【BZOJ4818】【SDOI2017】序列计数 [矩阵乘法][DP]
序列计数 Time Limit: 30 Sec Memory Limit: 128 MB [Submit][Status][Discuss] Description Alice想要得到一个长度为n的 ...
- [学习笔记]矩阵乘法及其优化dp
1.定义: $c[i][j]=\sum a[i][k]\times b[k][j]$ 所以矩阵乘法有条件,(n*m)*(m*p)=n*p 即第一个矩阵的列数等于第二个矩阵的行数,否则没有意义. 2.结 ...
- 【bzoj4870】[Shoi2017]组合数问题 dp+快速幂/矩阵乘法
题目描述 输入 第一行有四个整数 n, p, k, r,所有整数含义见问题描述. 1 ≤ n ≤ 10^9, 0 ≤ r < k ≤ 50, 2 ≤ p ≤ 2^30 − 1 输出 一行一个整数 ...
- 形态形成场(矩阵乘法优化dp)
形态形成场(矩阵乘法优化dp) 短信中将会涉及前\(k\)种大写字母,每个大写字母都有一个对应的替换式\(Si\),替换式中只会出现大写字母和数字,比如\(A→BB,B→CC0,C→123\),代表 ...
- BZOJ 1444 [JSOI2009]有趣的游戏 (AC自动机、概率与期望DP、矩阵乘法)
诶这题洛谷居然没有??? 题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1444 题解: 我见到主要有两种做法. 一是矩阵乘法.设\(d ...
- BZOJ 3329 Xorequ (数位DP、矩阵乘法)
BZOJ 3329 Xorequ (数位DP.矩阵乘法) 手动博客搬家: 本文发表于20181105 23:18:54, 原地址https://blog.csdn.net/suncongbo/arti ...
- 【学习笔记】浅谈广义矩阵乘法——动态DP
文章目录 广义矩阵乘法 动态DP 例题:洛谷4719 以下内容是本人做题经验,如有雷同,纯属抄袭:如有不对,纯属不懂,还请指正 广义矩阵乘法 众所周知,矩阵满足乘法交换律,前一个矩阵的列必须是后一个矩 ...
- 【2019牛客暑期多校训练营(第二场)- E】MAZE(线段树优化dp,dp转矩阵乘法,线段树维护矩阵乘法)
题干: 链接:https://ac.nowcoder.com/acm/contest/882/E?&headNav=acm 来源:牛客网 Given a maze with N rows an ...
最新文章
- oracle 分区表的建立方法
- 深入理解Python字符编码--转
- 大数据体系【协议】系列-1:gossip协议
- Oracle(3)——Oracle图形界面工具创建数据库
- IKVM:java代码c#调用
- 少儿编程几种语言_您使用了几种编程语言?
- SQL Server 2014 导入Excel
- Atiitt 使用java语言编写sql函数或存储过程
- 人去楼空 暴风影音倒闭 今后将成为历史?
- GD32VF103学习笔记(1)
- 平面方程(Plane Equation)求解方法
- 键盘鼠标是计算机标准输入输出设备,输入输出设备.ppt
- ARX中非模态对话框
- 2019年暑期GooGle SWE 凉经
- 第十九章《类的加载与反射》第3节:反射
- 什么是通达信接口函数
- Debian11之 RKE2 部署 K8S 集群
- GPS研究---GPS 系统的组成
- 常用CDK生成Java算法(大数异或)
- 〖教程〗LadonGO免杀Win10 Defender
热门文章
- 超速问题的c语言编程,超速行驶问题--精选.doc
- azure git怎么使用_Azure(一)Azure Traffic Manager为我们的Web项目提供负载均衡
- 如果__name__ =='__main__':在Python中怎么办?
- 怎样看虚拟主机的服务器,虚拟主机怎么查看服务器类型
- 远控免杀专题(22)-SpookFlare免杀
- 242. 有效的字母异位词 golang
- 744. 寻找比目标字母大的最小字母 golang
- 本能富可敌国,最后却选择拯救世界!Bram的Vim和乌干达儿童
- Xshell链接不上云服务器的解决方案
- 归并排序概念及其实现