URAL 1635
来源:互联网 发布:传智播客php笔记 编辑:程序博客网 时间:2024/05/29 11:10
题目大意:给出一个长为n的仅由小写英文字母组成的字符串,求它的回文串划分的元素的最小个数,并按顺序输出此划分。所谓回文划分就是将原字符串拆分成若干个回文子字符串。
Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u
数据规模:n<=4000。
理论基础:回文串定义:“回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。
题目分析:用dp[i]表示前i个字符的回文串划分的元素的最小值。pos[i]表示取得最小值时最后一个回文串所在位置的前一个位置。odd[i]表示以s[i]为中心的最长奇数回文串的偏移量,even[i]表示以s[i]==s[i+1]为中心的最长偶数回文串的偏移量。
那么,dp[i]=min(dp[i-k]+1,k为所有的以i为结束点的回文串的长度)。
代码如下:
#include <iostream>#include <cstring>using namespace std;#define N 4000int n,tot,odd[N+1],even[N+1],pos[N+1],d[N+1],dp[N+1],print[N+1];char s[N+5];int main(){ cin >> &s[1]; n=strlen(&s[1]); for (int i=1;i<=n;++i) { int l=i,r=i; while ((s[l] == s[r]) && l && (r <= n)) { odd[i]++; --l,++r; } l=i,r=i+1; while (l && (r <= n) && (s[l] == s[r])) { even[i]++; --l,++r; } } for (int i=1;i<=n;++i) { dp[i]=dp[i-1]+1; pos[i]=i-1; for (int j=(i+1)>>1;j;--j) { int p=i-(j<<1)+1,q=i-(((j<<1)-1)>>1); if (odd[q] >= j) { if (dp[p]+1 < dp[i]) { dp[i]=dp[p]+1; pos[i]=p; } } p=i-(j<<1),q=i-j; if (p < 0) continue; if (even[q] >= j) { if (dp[p]+1 < dp[i]) { dp[i]=dp[p]+1; pos[i]=p; } } } } cout << dp[n] << endl; while (n) { print[++tot]=n; n=pos[n]; } while (tot) { for (int i=print[tot+1]+1;i<=print[tot];++i)cout<<s[i]; --tot; tot?cout << ' ':cout<<'\n'; } return 0;}
其中dp方法有些变化,不过大体算法不变,参照题目分析与代码即可理解。
by:Jsun_moon http://blog.csdn.net/Jsun_moon
- Ural 1635
- Ural 1635
- URAL 1635
- URAL
- 【ural】
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- POJ 2245 Lotto (枚举)
- poj——1019(数学)
- 关于C/C++函数指针声明的理解
- Steve Yegge:Google面试秘籍
- build/core/base_rules.mk:195: already define
- URAL 1635
- 分类算法之决策树
- Linux内核高端内存
- asp.net WebForm程序删除.designer.cs文件,重新设计并绑定服务端控件时间
- Ural 1397. Points Game
- js等比缩放图片
- 未完成的旅行商问题
- 通配符是什么
- linux 编译系统的简单介绍与内核编译与安装