Light OJ 1044 Palindrome Partitioning (hash+DP)
2016-02-03 15:45
344 查看
题意:给出一个字符串,求其最少由多少个连续的回文子串构成。
解析:hash用来判一个子串是否是回文串,正反预处理保存各个位置上的hash值。
dp[i]:下标1~i对应的子串最少由多少个连续的回文子串构成。
dp[i] = min(dp[j-1]+1) (j<=i,且j到i能形成一个回文串)
解析:hash用来判一个子串是否是回文串,正反预处理保存各个位置上的hash值。
dp[i]:下标1~i对应的子串最少由多少个连续的回文子串构成。
dp[i] = min(dp[j-1]+1) (j<=i,且j到i能形成一个回文串)
: [code]#include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long LL; const LL MOD = 1e9+7; char s[1005]; int n,dp[1005]; LL Hash[2][1005],Mul[1005]; void hash(){ int i,j; Hash[0][0] = Hash[1][n+1] = 0; for(i = 1;i <= n;i++) Hash[0][i] = Hash[0][i-1]*MOD + s[i]; for(i = n;i >= 1;i--) Hash[1][i] = Hash[1][i+1]*MOD + s[i]; } bool check(int a,int b){ int mid = (b-a+2)/2; return Hash[0][a+mid-1]-Hash[0][a-1]*Mul[mid] == Hash[1][b-mid+1]-Hash[1][b+1]*Mul[mid]; } int main(){ int i,j,cas,T; Mul[0] = 1; for(i = 1;i < 1005;i++) Mul[i] = MOD*Mul[i-1]; scanf("%d",&cas); for(T = 1;T <= cas;T++){ scanf("%s",s+1); n = strlen(s+1); memset(dp,63,(n+1)*sizeof(int)); hash(); dp[0] = 0; for(i = 1;i <= n;i++){ for(j = i;j >= 1;j--){ if(check(j,i)){ dp[i] = min(dp[i],dp[j-1]+1); } } } printf("Case %d: %d\n",T,dp ); } return 0; }
相关文章推荐
- vi 打开多个文件
- kindle 退出演示模式
- Tip_压位
- java 反射机制构建JSON字符串
- java邮件解析1
- UVa 11181 条件概率
- Swift快速入门(一)第一个Swift程序
- Behave + Selenium(Python) 二
- php获取QQ头像并显示的方法
- react-native学习(一)
- php的include用法
- Android Studio 实用插件
- 【大型互联网企业架构分享】springmvc+mybatis+shiro+restful+webse
- SVG 路径简介
- OCP考点实战演练02-日常维护篇
- drozer环境搭建&基本命令
- apk 破解
- BeanFactory 和 ApplicationContext的区别
- HttpClient 教程 (一)
- 微信2015 年最热门的 10 篇技术文章,共 100 多篇精华