hdu 6086 -- Rikka with String(AC自动机 + 状压DP)
题目链接
Yuta has n 01 strings si, and he wants to know the number of 01 antisymmetric strings of length 2L which contain all given strings si as continuous substrings.
A 01 string s is antisymmetric if and only if s[i]≠s[|s|−i+1] for all i∈[1,|s|].
It is too difficult for Rikka. Can you help her?
In the second sample, the strings which satisfy all the restrictions are 000111,001011,011001,100110.
For each testcase, the first line contains two numbers n,L(1≤n≤6,1≤L≤100).
Then n lines follow, each line contains a 01 string si(1≤|si|≤20).
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <queue> #include <string> using namespace std; const int mod=998244353; const int N=2005; struct Node{int id;Node *fail;Node *son[2];int tag1,tag2; }node[N]; queue<Node *>q; int tot; int dp[2][2005][64];void insert1(string s,int id) {int len=s.length();Node *now=&node[0];for(int i=0;i<len;i++){int x=s[i]-'0';if(now->son[x]==NULL) now->son[x]=&node[tot++];now=now->son[x];}now->tag1|=(1<<id); } void insert2(string s,int id) {int len=s.length();Node *now=&node[0];for(int i=0;i<len;i++){int x=s[i]-'0';if(now->son[x]==NULL) now->son[x]=&node[tot++];now=now->son[x];}now->tag2|=(1<<id); } void init() {for(int i=0;i<N;i++){node[i].id=i;node[i].fail=NULL;node[i].son[0]=node[i].son[1]=NULL;node[i].tag1=node[i].tag2=0;} } void setFail() {Node* root=&node[0];q.push(root);while(!q.empty()){Node* now=q.front(); q.pop();for(int i=0;i<2;i++){if(now->son[i]){Node* p=now->fail;while(p && (!(p->son[i]))) p=p->fail;now->son[i]->fail=(p)?(p->son[i]):(root);now->son[i]->tag1|=now->son[i]->fail->tag1;now->son[i]->tag2|=now->son[i]->fail->tag2;q.push(now->son[i]);}else now->son[i]=(now!=root)?now->fail->son[i]:(root);}} } void print() {Node* now=&node[0];queue<Node*>qq;qq.push(now);while(!qq.empty()){now=qq.front(); qq.pop();cout<<"Y:"<<now->id<<" ";for(int i=0;i<2;i++){if(now->son[i]) qq.push(now->son[i]),cout<<now->son[i]->id<<" ";else cout<<"NULL"<<" ";}cout<<endl;} } int main() {///cout << "Hello world!" << endl; int t; cin>>t;while(t--){init();tot=1;int n,L; scanf("%d%d",&n,&L);for(int i=0;i<n;i++){string s; cin>>s;insert1(s,i);string t=s;reverse(t.begin(),t.end());int len=s.length();for(int j=0;j<len;j++)t[j]=(char)((t[j]-'0')^1+'0');insert1(t,i);int mnLen=min(len,L);for(int j=0;j<mnLen;j++){int f=1;for(int l=j,r=j+1; l>=0&&r<len; l--,r++){if((s[l]^s[r])==0) { f=0; break; }}if(!f) continue;t=s.substr(0,j+1);for(int k=2*j+2;k<len;k++){t=(char)((s[k]-'0')^1+'0')+t;}insert2(t,i);}}///print(); setFail();memset(dp,0,sizeof(dp));dp[0][0][0]=1;int cn=0,stu=(1<<n);for(int i=0;i<L;i++){int c=cn^1;memset(dp[c],0,sizeof(dp[c]));for(int j=0;j<tot;j++){for(int s=0;s<stu;s++){if(!dp[cn][j][s]) continue;if(i<L-1)for(int k=0;k<2;k++){int x=node[j].son[k]->id;int tag=node[x].tag1;dp[c][x][s|tag]=(dp[c][x][s|tag]+dp[cn][j][s])%mod;}elsefor(int k=0;k<2;k++){int x=node[j].son[k]->id;int tag=node[x].tag1|node[x].tag2;dp[c][x][s|tag]=(dp[c][x][s|tag]+dp[cn][j][s])%mod;}}}cn=c;}int ans=0;for(int i=0;i<tot;i++){ans=(ans+dp[cn][i][stu-1])%mod;}printf("%d\n",ans);}return 0; }
转载于:https://www.cnblogs.com/chen9510/p/7406636.html
hdu 6086 -- Rikka with String(AC自动机 + 状压DP)相关推荐
- hdu 6086 Rikka with String(AC自动机+状压dp)
题目链接:hdu 6086 Rikka with String 题意: 给你n个只含01的串,和一个长度L,现在让你构造出满足s[i]≠s[|s|−i+1] for all i∈[1,|s|] ,长度 ...
- HDU - 3341 Lost's revenge(AC自动机+状压dp)
题目链接:点击查看 题目大意:给出 n 个模式串,最后给出一个匹配串,问如何重新排列匹配串,可以使得匹配串尽可能多的匹配模式串 题目分析:因为是模式串和匹配串的匹配,所以考虑AC自动机,因为数据范围比 ...
- HDU - 2825 Wireless Password(AC自动机+状压dp)
题目链接:点击查看 题目大意:给出 m 个匹配串,问长度为 n 的字符串中,至少包含 k 个匹配串(可重叠)的字符串有多少个 题目分析:考虑到n,m,k都特别小,所以可以先用AC自动机将状态关系转移出 ...
- HDU - 3247 Resource Archiver(AC自动机+状压dp+bfs)
题目链接:点击查看 题目大意:给出 n 个目标串和 m 个病毒串,要求构造出一个长度最短的,且包含全部 n 个目标串,但是不能包含任意一个病毒串的01字符串,输出其最短长度 题目分析:比较综合的一道题 ...
- HDU - 2825 Wireless Password (AC自动机 + 状压dp)
题目链接 题意 求至少包含KKK个给定字符串长度为NNN的字符串 思路 把所有可能的字符串建AC自动机,遍历所有节点dp[i][j][k]dp[i][j][k]dp[i][j][k] 表示以节点jjj ...
- 【hdu2825】ac自动机 + 状压dp
传送门 题目大意: 给你一些密码片段字符串,让你求长度为n,且至少包含k个不同密码片段串的字符串的数量. 题解: 因为密码串不多,可以考虑状态压缩 设dp[i][j][sta]表示长为i的字符串匹配到 ...
- AC自动机+状压dp hdu2825 Wireless Password
传送门:点击打开链接 题意:有个密码长度为n,现在有m个魔力单词,要求密码中魔力单词的种类数>=k,问这种密码的种类数. 思路:和之前一样,我们会想到AC自动机去压缩状态,把状态给简化.然后我们 ...
- P4045-[JSOI2009]密码【AC自动机,状压dp】
正题 题目链接:https://www.luogu.com.cn/problem/P4045 题目大意 给nnn个字符串,求有多少个长度为lll的字符串包含所有给出的字符串 解题思路 因为nnn很小, ...
- *【HDU - 4272 】LianLianKan (dfs 或 状压dp,贪心不行)
题干: I like playing game with my friend, although sometimes looks pretty naive. Today I invent a new ...
最新文章
- 实践 Neutron 前的两个准备工作 - 每天5分钟玩转 OpenStack(78)
- centos 重启网卡_CentOS7网络配置和修改网卡名称及常用服务管理命令
- web3@0.20.1 在依据abi创建智能合约的时候报错 TypeError: web3.eth.contract is not a function
- hibernate 程序运行时的错误,及解决办法(不定期更新)
- failed to open log file_C++中glog源码剖析以及如何设计一个高效 log模块
- charles工具页面介绍
- columns列:Rows 工作表上所有的行
- 6.Java反射到底慢在哪
- 线性表的总结:顺序存储线性表的初始化,创建,插入,删除,清空,销毁等操作...
- Hyperledger Fabric 节点类型Commiter、Endorser、Leader、Anchor
- java8计算两个日期之间的天数
- 免费直播|1小时详解区块链技术
- 电子器件系列二十一:混频器
- Windows cmd常用命令
- html5 地铁 代码,基于HTML5WebGL的地铁管理系统
- 网络编辑必知常识:什么是PV、UV和PR值
- ONEDNS配置1:centos7DNS服务器forwarder配置
- 每个c语言程序文件的编译错误被分为什么,已打印中央电大C语言考试题库(c语言小题+编程)...
- 硬件在环系统环境架构
- 经济学方面的电子书挺多
热门文章
- 【POJ - 3320 】Jessica's Reading Problem (尺取,哈希)
- 动手学无人驾驶(4):基于激光雷达点云数据3D目标检测
- 11.Pipelines
- java web svn_如何搭建svnadmin,一个简单的svnWEB页面
- 判断集合相等_数学启蒙的每个关键阶段之集合分类
- Callable创建多线程
- char qt 转unicode_Qt QString 中文 char* UTF-8 QByteArray QTextCodec unicode gb2312 GBK 乱码与转码问题...
- Jquery 全选,反选
- 学习笔记1-Linux1
- 求1~n这n个整数十进制表示中1出现的次数