Codeforces 557E - Ann and Half-Palindrome (字典树+DP)
2015-07-27 18:06
435 查看
首先一个N方的DP处理出哪些串是半回文串。对于输出字典序第K个这种问题可以使用字典树。
先一个dfs计算出字典树中每个节点下面的子树中共有多少半回文串,然后在输出时,递归引入参数K,如果K小于左子树回文串数,说明此处应该输出a,向左走。否则要把K-=左子树回文子串数,然后输出b进右边,直到K<=0。
插入时不能一个子串一个子串插,因为插入是O(N)的,那样总时间就是N^3的了。要一次性把同一起点的所有子串都插入。
代码:
先一个dfs计算出字典树中每个节点下面的子树中共有多少半回文串,然后在输出时,递归引入参数K,如果K小于左子树回文串数,说明此处应该输出a,向左走。否则要把K-=左子树回文子串数,然后输出b进右边,直到K<=0。
插入时不能一个子串一个子串插,因为插入是O(N)的,那样总时间就是N^3的了。要一次性把同一起点的所有子串都插入。
代码:
#include <iostream> #include <cstdio> #include <cstring> using namespace std; #define maxn 5005 char s[5005]; bool dp[5005][5005]; int ch[maxn*maxn][2]; int ed[maxn*maxn]; int num[maxn*maxn]; int sz; void Init(){ sz=1 ; memset(ch[0],0,sizeof(ch[0])); } int idx(char c) { return c-'a'; } int len; void Insert(int a){ int u=0; for(int i=a;i<len;i++){ int c=idx(s[i]); if(!ch[u][c]){ ed[sz]=0; ch[u][c]=sz++; } u=ch[u][c]; if(dp[a][i]) ed[u]++; } } int K; int cur; bool OK=0; void Print(int n,int K){ K-=ed ; if(K<=0) return ; int l=ch [0],r=ch [1]; if(l){ if(num[l]>=K){ printf("a"); Print(l,K); } else{ K-=num[l]; printf("b"); Print(r,K); } } else { printf("b"); Print(r,K); } } void dfs(int n){ if(ch [0]){ dfs(ch [0]); num +=num[ch [0]]; } if(ch [1]){ dfs(ch [1]); num +=num[ch [1]]; } if(ed ) num +=ed ; } int main(){ scanf("%s",s); scanf("%d",&K); len=strlen(s); Init(); for(int i=0;i<len;i++){ dp[i][i]=1; } for(int i=0;i<len-1;i++){ if(s[i]==s[i+1]){ dp[i][i+1]=1; } } for(int i=0;i<len-2;i++){ if(s[i]==s[i+2]){ dp[i][i+2]=1; } } for(int i=0;i<len-3;i++){ if(s[i]==s[i+3]){ dp[i][i+3]=1; } } for(int i=5;i<=len;i++){ for(int j=0;j<len-i+1;j++){ if(dp[j+2][j+i-3]&&s[j]==s[j+i-1]){ dp[j][j+i-1]=1; } } } for(int i=0;i<len;i++) Insert(i); dfs(0); Print(0,K); return 0; }
相关文章推荐
- 短信拦截再总结
- 使用Spring Boot和Gradle创建AngularJS项目
- HDU 3271-SNIBB(数位dp)
- HDU1052——田忌赛马(贪心)
- 欢迎使用CSDN-markdown编辑器
- 【C语言】3子棋游戏,
- NYOJ 找数达人 (找n个数构成m是否存在)
- 怎样将整型变量转换为字符变量 然后串口 或者LCD发送出来(STM32) 以及sprintf的用法
- Android视频播放开源库vitamio
- Xcode 快捷键
- Spark1.4.1 编译与安装
- 如何成功实施SDL提供的官方Android平台Demo
- 通知
- 面向对象
- 点击手机物理键返回
- Activiti使用maven alfresco仓库问题处理
- iOS 获取汉字拼音首字母
- codeforce Gym 100500C ICPC Giveaways(水)
- 前端关于JSON的一些基础知识
- HDU 2925 Musical Chairs(约瑟夫环问题)