AC自动机+DP。题目要求是生成一个长度为n的 0-1 串,其中最长回文子串的长度小于 k ( 1 <= k <= 10)。因为k长度只有10,所以我们可以先预处理出长度小于11的所有回文串,然后利用找出的回文串建立AC自动机,然后生成一个长度为n的满足题意的串就可以了。AC自动机中节点信息保存为到达该点最长的回文串长度,这样就可以保证利用自动机产生子回文串小于 k 的串了,因为一旦到达长度大于k的节点我们就不向下更新就可以了。至于为什么我们建立自动机的时候只找长度小于11的,明显这是因为我们需要的最长的回文子串是9嘛,而为了让生成的串长度不大于9,我们需要防止回文串由9直接加两个变成11,这样就不满足题意了。。。所以需要判断下一步会不会产生长度11的串。。。这题有非AC自动机的DP做法,时空效率都很高,同学们可以去搜一下。。。

#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstdlib>
#include <climits>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <cctype>
#include <queue>
#include <cmath>
#include <set>
#include <map>
#define CLR(a, b) memset(a, b, sizeof(a))
using namespace std;const int MAX_NODE = 2000 * 2;
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;
const int CHILD_NUM = 2;
const int N = 11;class ACAutomaton
{
private:int chd[MAX_NODE][CHILD_NUM];int fail[MAX_NODE];int val[MAX_NODE];int Q[MAX_NODE];int ID[128];int sz;
public:void Initialize(){fail[0] = 0;ID['0'] = 0; ID['1'] = 1;}void Reset(){CLR(chd[0] , 0);sz = 1;CLR(val, 0);}void Insert(char *a, int sit){int p = 0;for ( ; *a ; a ++){int c = ID[*a];if (!chd[p][c]){CLR(chd[sz] , 0);chd[p][c] = sz ++;}p = chd[p][c];}val[p] = sit;}void Construct(){int *s = Q , *e = Q;for (int i = 0 ; i < CHILD_NUM ; i ++){if (chd[0][i]){fail[ chd[0][i] ] = 0;*e ++ = chd[0][i];}}while (s != e){int u = *s++;for (int i = 0 ; i < CHILD_NUM ; i ++){int &v = chd[u][i];if (v){*e ++ = v;fail[v] = chd[fail[u]][i];val[v] = max(val[v], val[fail[v]]);}else{v = chd[fail[u]][i];}}}}int dp[2][MAX_NODE][12];int Work(int n, int k){CLR(dp, 0);dp[0][0][0] = 1;for(int i = 0; i < n; i ++){CLR(dp[(i + 1) & 1], 0);for(int j = 0; j < sz; j ++){if(val[j]  < k && (val[chd[j][0]] < k || val[chd[j][1]] < k)) for(int s = 0; s < k; s ++){if(!dp[i & 1][j][s]) continue;int c = chd[j][0], tp;tp = max(val[c], s);if(tp < k)dp[(i + 1) & 1][c][tp] = (dp[(i + 1) & 1][c][tp] + dp[i & 1][j][s]) % MOD;c = chd[j][1];tp = max(val[c], s);if(tp < k)dp[(i + 1) & 1][c][tp] = (dp[(i + 1) & 1][c][tp] + dp[i & 1][j][s]) % MOD;}}}int ret = 0;for(int i = 1; i < sz; i ++){for(int j = 0; j < k; j ++){ret = (ret + dp[n & 1][i][j]) % MOD;}}return ret;}
} AC;char ch1[N + 1], ch2[N + 1];int ok(int x)
{int a[N], ret = 0;while(x){if(x & 1) a[ret ++] = 1;else a[ret ++] = 0;x >>= 1;}for(int i = 0; i <= ret / 2; i ++){if(a[i] != a[ret - 1 - i]) return 0;}return ret;
}int main()
{int t, n, k;AC.Initialize();AC.Reset();for(int i = 1; i < (1 << N); i ++){int s = ok(i), ret; ret = s;if(s){int x = i;ch2[s] = ch1[s] = '\0';while(x){if(x & 1) ch1[-- s] = '1', ch2[s] = '0';else ch1[-- s] = '0', ch2[s] = '1';x >>= 1;}AC.Insert(ch1, ret);AC.Insert(ch2, ret);}}AC.Construct();scanf("%d", &t);while(t --){scanf("%d%d", &n, &k);printf("%d\n", AC.Work(n, k));}
}

SPOJ AMR12E Dyslexic Gollum相关推荐

  1. SPOJ AMR12E Dyslexic Gollum 解题报告

    题目 Summer Training 06 - Amritapuri 2012 总结 题意: 在所有长度为n的01串中,不包含长度大于等于K的回文字串的串有多少个. 题解: 注意到K非常小,所以可以用 ...

  2. 【UVa】【DP】1633 Dyslexic Gollum

    UVa 1633 Dyslexic Gollum 题目 ◇题目传送门◆(由于UVa较慢,这里提供一份vjudge的链接) ◇题目传送门(vjudge)◆ 题目大意 输入正整数N,KN,KN,K,求长度 ...

  3. UVA 1633 Dyslexic Gollum (状压dp)

    分析:dp[i][j]表示当前为i长度,长度为k的后缀状态,有多少个串.考虑一下k和k+1长度的串是否为回文串即可 代码: #include <iostream> #include < ...

  4. Dyslexic Gollum

    题意: 求长度是n的二进制串中,不含长度大于等于k的回文串的个数 分析: dp[i][j][k]表示长度i,后11位状态是j不含长度大于等于k的回文串的个数(因为k最大是10,所把后11位状态压缩,d ...

  5. UVA 1633 Dyslexic Gollum

    有一定难度的一道动态规划的题目.这个题目首先计算palindrom[i][j],其中i表示对应的数据的位数,j表示相应的数据,palindrom[i][j]中记录的就是i位二进制位表示的数据j是否为回 ...

  6. 禁止的回文子串 Dyslexic Gollum

    UVA1633 一个长的回文串都可以由短的回文串拓展而来,只要短的回文在左右两端增加相同的字符即可.因此,在考虑长度为NNN的01串时,只要在从长度为1向NNN拓展的过程中,保证后KKK个字符不是回文 ...

  7. 【题解】UVA1633:Dyslexic Gollum

    @vjudge 只要保证不出现长度为kkk或k+1k+1k+1的回文串就可以 状压保存最后kkk位的状态,每次转移时判断一下是否合理就好了 Code: #include <bits/stdc++ ...

  8. UVa 1633 Dyslexic Gollum(状压DP)

    题意 求有多少长度等于N(N≤400)N(N\leq 400)N(N≤400)的∑={0,1}\sum = \{0,1\}∑={0,1}字符串里面不包含长度大于等于k(k≤10)k(k \leq 10 ...

  9. UVA - 1633 Dyslexic Gollum 状态压缩

    问题 输入N,K(N<=400,K<=10),求长度为N且不含有长度至少为K的连续回文子串的01字符串有多少个? 分析 输入k,要判断k,k+1的情况,因为一个字符串有长度为k的回文子串, ...

最新文章

  1. Python中的张量分解
  2. 请求Get和Post对于utf-8字符的处理的考虑
  3. EF架构~为EF DbContext生成的实体添加注释(T4模板应用)
  4. Matlab下 IIR 滤波器实现(Simulink仿真和C语言实现)
  5. docker报错:OCI runtime create failed...process_linux.go:449: container init caused “write /proc/self/
  6. 【转】oracle having -OCP-047-53
  7. lts安装 rust ubuntu_一起学Rust编程「1」:开发环境
  8. python窗口图形界面编程上传图片_python GUI编程(Tkinter) 创建子窗口及在窗口上用图片绘图实例...
  9. WebLogic中如何设置Spring Boot项目的属性
  10. 服务器端口映射到公网不通解决方法
  11. 微醺的夜,胡乱的文字,迷失的我
  12. SONiC:为Microsoft全球云提供支持的网络交换机软件
  13. 详解如何使用 DosBox 安装 Windows 95 操作系统
  14. 大数据时代的 10 个重大变化
  15. 比湿,相对湿度和绝对湿度
  16. APP设计说明书概述
  17. 司马相如和卓文君——野史+臆想
  18. Nginx通过ip和user_gent限制访问
  19. mybatis 插件机制
  20. 2022淘宝双11喵果总动员怎么玩?天猫双十一喵果组队玩法攻略

热门文章

  1. retrofit2.adapter.rxjava2.HttpException: HTTP 403 Forbidden
  2. MySQL之部门编号排序
  3. 单细胞RNA测序研究的实验设计指南(部分阅读)
  4. numpy—np.isnan
  5. zan php demo,zanphp源码解读 - 应用的启动
  6. iis5.1(xp)发布网站(转)
  7. 别高估自己1年的成就,却低估自己10年的发展
  8. Linux mount umount 的理解
  9. 浏览器如何查看已保存密码
  10. 编译原理之算符优先分析语法程序