SPOJ 1676 矩阵乘法+DP

题意:

给定N (1 ≤ N ≤ 10)个长度不超过6的单词,求由大写字母组成长度为L的包含至少一个给定单词的字符串有多少种,答案 mod 10007,(1 ≤ L ≤ 10^6)。

 

题解:

这个题最早是在一个关于trie图的论文中看到了,最近jzh又讲到了这个题,于是就把它做了~

大致有两种做法,两种方法都需要矩阵乘法加速

1、trie图中的dp

2、直接人工减少转移数量

具体做法点击这里

 

大致思路就是将不可能构成单词的前缀合成一类,然后胡搞就行了。

 

View Code
  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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/400875.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java并发编程实战

程序等待某个同步IO操作完成&#xff0c;CPU将处于空间状态。 线程安全---多个线程交替访问某个类&#xff0c;调用方不需做任何的同步&#xff0c;这个类始终表现出正确的行为 不共享变量变量是不可变访问变量使用同步synchronized除了实现原子性&#xff08;确定临界区&#…

spring mvc ModelAndView向前台传值

今天在做项目的时候遇到一个问题&#xff0c;把第一个页面保存的id传到第三个页面中去用&#xff0c;原来是在controller层加了一个全局变量控制的&#xff0c;可是后来发现这个变量实现不了我要的功能&#xff0c;于是查了一下&#xff0c;原来ModelAndView这个类有个构造方法…

go-zero微服务实战系列(三、API定义和表结构设计)

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

mongo经验总结

http://wenku.baidu.com/view/7c279cbfc77da26925c5b0e4.html转载于:https://www.cnblogs.com/yuechaotian/archive/2013/02/19/2916692.html

STM32 串口DMA接收 Openmv / K210 整数、小数字符串数据 (基于HAL库)

目录前言一、工程配置二、串口DMA部分代码1.源文件UART_DMA.c2.头文件UART_DMA.h3.stm32f1xx_it.c的修改4.串口收发DMA测试三、字符串数字提取代码1.源文件NumAndStr.c:2.头文件NumAndStr.h:3.测试:四、Openmv / K210 发送、STM32接收测试总结修订版本UART_DMA.cUART_DMA.h平台…

6000字|22张图 带你彻底弄懂Zookeeper分布式锁

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

静态与非静态(转改)

这里有一个C的测试&#xff0c;由于c#的sizeof不能对一般类使用&#xff0c;所以没法试验。 class Test {int i;static int j;void Method1() { printf("Method1"); };void Method2() { printf("Method2"); };void Method3() { printf("Method3"…

【HDU2896】病毒侵袭——ac自动机

网上很多代码都略显繁琐&#xff0c;看了一下yy dalao的代码感觉很好&#xff0c;但他懒得打题解&#xff08;好吧我也是 以0为根节点的话&#xff0c;我把yy的一段代码删了改用fail[c]x0?0:ch[fail[x]][i];来实现特判&#xff0c;效果还不错&#xff01;也算是AC自动机的模版…

经典 HTML5 Javascript 俄罗斯方块游戏

Blockrain.js 是一个使用 HTML5 & JavaScript 开发的经典俄罗斯方块游戏。只需要复制和粘贴一段代码就可以玩起来了。最重要的是&#xff0c;它是响应式的&#xff0c;无论你的显示屏多么宽都能自动匹配。你可以自定义你想要的颜色以适应您的网站&#xff0c;也可以调整方块…

【电赛PID半天入门】从接触编码器到调出好康的PID波形

从接触编码器到调出好康的PID波形认识电机及编码器只需动动手指&#xff0c;就能让STM32得到电机转过的角度让电机转起来认识PID控制①比例调节器②积分调节③微分调节④比例积分微分调节数字PID调节器&#xff08;1&#xff09;数字PID位置型控制算法&#xff08;2&#xff09…

算法的复杂度分析

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

PHP面向对象 封装与继承

知识点&#xff1a; PHP封装三个关键词&#xff1a; 一、public 公有的&#xff0c;被public修饰的属性和方法&#xff0c;对象可以任意访问和调用 二、private 私有的&#xff0c;被private修饰的属性和方法&#xff0c;只能在类内部的方法可以进行调用&#xff0c;或者被子类…

POJ 1380 坐标旋转

题意&#xff1a; 问第二个矩形能不能放进第一个矩形中。 题解&#xff1a; 暴力旋转第二个矩形&#xff0c;判断左右、上下是否同时小于第一个矩形 当然&#xff0c;数学推导也可以&#xff0c;挺简单的相似神马的胡搞就行~ View Code 1 #include <iostream>2 #include…

冲刺省选习题集

1.火柴棒等式 单击此处看题目 考察算法&#xff1a;数学分析枚举 1 #include <iostream>2 #include <cstdio>3 using namespace std;4 5 const int match[10]{6,2,5,5,4,5,6,3,7,6};6 7 int n;8 9 int merge(int x){ 10 int sum0; 11 if(x0)return 6; 12 …

MSP430F5529 DriverLib 库函数学习笔记(一)时钟配置和闪烁LED

目录一、新建工程二、时钟树时钟系统结构时钟系统的原理时钟树配置实战三、点灯工程师封装好的初始化函数平台&#xff1a;Code Composer Studio 10.3.1 MSP430F5529 LaunchPad™ Development Kit (MSP‑EXP430F5529LP) 一、新建工程 二、时钟树 时钟系统结构 &#xff08;1&…

解决maven依赖冲突,这篇就够了!

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

SOAP 1.1 - 学习

SOAP 1.1 --- 每天发送SOAP request&#xff0c;不搞明白啥叫SOAP,惭愧 SOAP 1.1 XML 架构定义 <xs:schema xmlns:xs"http://www.w3.org/2001/XMLSchema" xmlns:tns"http://schemas.xmlsoap.org/soap/envelope/" targetNamespace"h…

Codeforces Round #168 (Div. 2)---A. Lights Out

Lights Outtime limit per test2 secondsmemory limit per test256 megabytesinputstandard inputoutputstandard outputLenny is playing a game on a 3  3 grid of lights. In the beginning of the game all lights are switched on. Pressing any of the lights will tog…

【C#/VB.NET】 将PDF转为SVG/Image, SVG/Image转PDF

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

hiho模拟面试题2 补提交卡 (贪心,枚举)

题目&#xff1a; 时间限制:2000ms单点时限:1000ms内存限制:256MB描写叙述 小Ho给自己定了一个雄伟的目标&#xff1a;连续100天每天坚持在hihoCoder上提交一个程序。100天过去了。小Ho查看自己的提交记录发现有N天由于贪玩忘记提交了。于是小Ho软磨硬泡、强忍着小Hi歧视的眼神…