题目大意:有个人想破解他邻居的密码,他邻居告诉了一些关于这个密码的信息,并且给他一个单词集合,他用这些信息判断一下最少有多少种密码。
1->, 所有的密码都是有小写字母组成。
2->,密码的长度是 n (1<= n <=25)。
3->,密码至少包含 k 种字符集里面的单词。
 
比如,给集合{"she", "he"},单词长度是3,最少包含两个单词的密码,很明显只能是“she”(题目表述的不清楚)。
 
分析:因为要统计记录到达每个点时候经过多少种不同的单词,所以需要用一种方法来保存这些信息,开一个数组来判重貌似是个很容易想到的办法,不过考虑时间复杂度的问题,建议还是不要这么干,因为字符集合的数量很少,只有10,所以我们可以使用状态压缩来保存这些信息,而且转移状态时候也很方便操作,不过有点需要注意,一定要把遍历子节点放在最内层循环,这样再遍历每一种状态的时候发先有0的情况可以continue一下,否则超时超的哇哇的.......
 
代码如下:
==========================================================================
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std; const int MAXN = ;
const int MaxSon = ;
const int Mod = ;
const int oo = 1e9+; struct Ac_Trie
{
int next[MAXN][MaxSon];
int Fail[MAXN], End[MAXN];
int cnt, root; int newnode()
{
for(int i=; i<MaxSon; i++)
next[cnt][i] = -;
Fail[cnt] = End[cnt] = false; return cnt++;
}
void InIt()
{
cnt = ;
root = newnode();
} void Insert(char s[], int t)
{
int now = root; for(int i=; s[i]; i++)
{
int k = s[i]-'a'; if(next[now][k] == -)
next[now][k] = newnode();
now = next[now][k];
} End[now] = <<t;
}
void GetFial()
{
queue<int>Q;
int now = root; for(int i=; i<MaxSon; i++)
{
if(next[now][i] == -)
next[now][i] = root;
else
{
Fail[next[now][i]] = root;
Q.push(next[now][i]);
}
} while(Q.size())
{
now = Q.front();
Q.pop(); for(int i=; i<MaxSon; i++)
{
if(next[now][i] == -)
next[now][i] = next[Fail[now]][i];
else
{
Fail[next[now][i]] = next[Fail[now]][i];
Q.push(next[now][i]);
}
} End[now] |= End[Fail[now]];
}
}
};
Ac_Trie ac; int Find(int i)
{
int k=; while(i)
{
if(i % )
k++;
i /= ;
} return k;
} int main()
{
int N, M, K; int sum[] ={}; for(int i=; i<; i++)
sum[i] = Find(i); while(scanf("%d%d%d", &N, &M, &K), N+M+K)
{
char s[MAXN];
ac.InIt(); for(int i=; i<M; i++)
{
scanf("%s", s);
ac.Insert(s, i);
} ac.GetFial(); int dp[][MAXN][] = {}, op=, Len = <<M;
dp[][][] = ; while(N--)
{
memset(dp[op], , sizeof(dp[op])); for(int i=; i<ac.cnt; i++)
for(int k=; k<Len; k++)
{///把k放中间优化一下...否则超时
if(dp[op^][i][k] == )
continue; for(int j=; j<MaxSon; j++)
{
(dp[op][ac.next[i][j]][k|ac.End[i]] += dp[op^][i][k])%=Mod;
}
} op ^= ;
} int ans = ; for(int i=; i<ac.cnt; i++)
for(int j=; j<Len; j++)
{
if(sum[j] >= K || sum[ac.End[i]|j] >= K)
{
ans += dp[op^][i][j];
ans %= Mod;
}
} printf("%d\n", ans);
} return ;
}

Wireless Password - HDU 2825(ac自动机+状态压缩)的更多相关文章

  1. hdu 2825(ac自动机+状态压缩dp)

    题意:容易理解... 分析:在做这道题之前我做了hdu 4057,都是同一种类型的题,因为题中给的模式串的个数最多只能为10个,所以我们就很容易想到用状态压缩来做,但是开始的时候我的代码超时了dp时我 ...

  2. HDU 4511 (AC自动机+状态压缩DP)

    题目链接:  http://acm.hdu.edu.cn/showproblem.php?pid=4511 题目大意:从1走到N,中间可以选择性经过某些点,比如1->N,或1->2-> ...

  3. hdu 4057(ac自动机+状态压缩dp)

    题意:容易理解... 分析:题目中给的模式串的个数最多为10个,于是想到用状态压缩dp来做,它的状态范围为1-2^9,所以最大为2^10-1,那我们可以用:dp[i][j][k]表示长度为i,在tri ...

  4. hdu 3341(ac自动机+状态压缩)

    题意:容易理解... 思路:首先一开始容易想到要用到dp,开设一个dp[41][41][41][41][501]的数组来解决,但是明显内存已经超出范围了,于是就想如何减少内存呢?只要知道A.T.C.G ...

  5. hdu 2825 aC自动机+状压dp

    Wireless Password Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  6. HDU 4057 Rescue the Rabbit ( AC自动机 + 状态压缩DP )

    模板来自notonlysuccess. 模式串只有10个,并且重复出现的分值不累加,因此很容易想到状态压缩. 将模式串加入AC自动机,最多有10*100个状态. dp[i][j][k]:串长为i,在T ...

  7. HDU 4758 Walk Through Squares( AC自动机 + 状态压缩DP )

    题意:给你两个串A,B, 问一个串长为M+N且包含A和B且恰好包含M个R的字符串有多少种组合方式,所有字符串中均只含有字符L和R. dp[i][j][k][S]表示串长为i,有j个R,在自动机中的状态 ...

  8. POJ 3691 (AC自动机+状态压缩DP)

    题目链接:  http://poj.org/problem?id=3691 题目大意:给定N个致病DNA片段以及一个最终DNA片段.问最终DNA片段最少修改多少个字符,使得不包含任一致病DNA. 解题 ...

  9. bzoj1195 神奇的ac自动机+状态压缩dp

    /* 难的不是ac自动机,是状态压缩dp 之前做了一两题类似题目,感觉理解的还不够透彻 */ #include<iostream> #include<cstdio> #incl ...

随机推荐

  1. php中调用其他系统http接口的方法说明

    使用函数: file_get_contents($url); 传入接口url及其参数:如 $url="http://192.168.1.1/test.jsp?id=1&type=2& ...

  2. 收集 数据库的awr数据,生成报告

    该脚本只是把awr报告的内容,原封不动的 展现出来,做记录 awrreport.sql  脚本内容如下: *********************************************** ...

  3. Swift - 使用CoreLocation实现定位(经纬度、海拔、速度、距离等)

    CoreLocation是iOS中一个提供设备定位的框架.通过这个框架可以实现定位处理,从而获取位置数据,比如经度.纬度.海拔信息等.   1,定位精度的设置 定位服务管理类CLLocationMan ...

  4. Jquery 点击空白处消失

    $(document).bind("click", function (e){ if ( $((e.target || e.srcElement)).closest("# ...

  5. python - StringIO文本缓冲

    参考:http://pymotwcn.readthedocs.org/en/latest/documents/StringIO.html 类StringIO提供了一个在内存中方便处理文本的类文件(读, ...

  6. Overloads和Overrides在元属性继承上的特性

    元属性继承可以使用IsDefined函数进行判断,先写出结论 如果使用Overrides,则元属性可以继承,除非在使用IsDefined时明确不进行继承判断,如 pFunction.IsDefined ...

  7. MySql数据库1【概念】

    [mysql] mysql是目前最主流的跨平台.开放源代码的关系型数据库,由瑞曲的mysql ab公司开发,已经被SUN公司收购,标识是一只名为sakila的海豚,代表mysql的速度.能力.精确优秀 ...

  8. Day13 SQLAlchemy连表操作和堡垒机

    一.数据库操作 1.创建表.插入数据和一对多查询 #!/usr/bin/env python # -*- coding: utf-8 -*- # Author: wanghuafeng from sq ...

  9. 常用的gnuradio 模块

    ---恢复内容开始--- 参考:http://gnuradio.org/redmine/projects/gnuradio/wiki/TutorialsWritePythonApplications ...

  10. 删除svn文件

    删除svn文件 sudo find . -name ".DS_Store" -exec rm -r {} \; sudo find . -name ".git" ...