划分成回文串(uva 11584)
2018-03-27 19:21
295 查看
题目链接 https://cn.vjudge.net/problem/UVA-11584
【题意】
输入一个由小写字母组成的字符串,你的任务是把它们划分成尽量少的回文串。比aaadbccb至少要划分成3个回文串,aaa,d,bccb 字符串长度不超过1000
【思路】
设dp(i)表示字符串s[0]到s[i]的子串可以划分成回文串的最少个数,那么状态转移方程为dp(i)=min{dp(j)+1 | s[j+1]~s[i]是回文串} 在递推求解之前需要先预处理出原字符串s[i]~s[j]是否为回文串,可以枚举每个字符和每两个字符为中点,然后向两边延伸,复杂度是O(n^2),之后递推的过程复杂度也是O(n^2),总的时间复杂度也就为O(n^2)
【题意】
输入一个由小写字母组成的字符串,你的任务是把它们划分成尽量少的回文串。比aaadbccb至少要划分成3个回文串,aaa,d,bccb 字符串长度不超过1000
【思路】
设dp(i)表示字符串s[0]到s[i]的子串可以划分成回文串的最少个数,那么状态转移方程为dp(i)=min{dp(j)+1 | s[j+1]~s[i]是回文串} 在递推求解之前需要先预处理出原字符串s[i]~s[j]是否为回文串,可以枚举每个字符和每两个字符为中点,然后向两边延伸,复杂度是O(n^2),之后递推的过程复杂度也是O(n^2),总的时间复杂度也就为O(n^2)
#include<bits/stdc++.h> using namespace std; const int inf=2e9; const int maxn=1050; int len; char s[maxn]; int dp[maxn]; bool ok[maxn][maxn]; void judge(){ memset(ok,0,sizeof(ok)); for(int i=0;i<len;++i){//枚举每个s[i]作为中心的子串是否是回文串 ok[i][i]=true; for(int j=1;;++j){ int p=i-j; int q=i+j; if(p<0||q>=len) break; if(s[p]==s[q]) ok[p][q]=true; else break; } } for(int i=0;i<len-1;++i){//枚举每个s[i]和s[i+1]作为中心的子串是否是回文串 if(s[i]!=s[i+1]) continue; ok[i][i+1]=true; for(int j=1;;++j){ int p=i-j; int q=i+1+j; if(p<0||q>=len) break; if(s[p]==s[q]) ok[p][q]=true; else break; } } } int main(){ int t; scanf("%d",&t); while(t--){ scanf("%s",s); len=strlen(s); judge(); dp[0]=1; for(int i=1;i<len;++i){ if(ok[0][i]) { dp[i]=1; continue; } int ans=inf; for(int j=0;j<i;++j){ if(ok[j+1][i]) ans=min(ans,dp[j]+1); } dp[i]=ans; } printf("%d\n",dp[len-1]); } return 0; }
相关文章推荐
- uva 划分成回文串 11584 题解
- 例题9-7 划分成回文串 UVa11584
- uva11584 划分成回文串
- UVA11584 划分成回文串
- UVa 11584 划分成回文串
- UVA 11584 Partitioning by Palindromes 划分成回文串(DP + 预处理)
- UVA 11584 或 BNU20002 划分成回文串 DP求一个串最少能划分成多少个文回串
- uva11584 划分成回文串
- uva 11584 划分成回文串
- uva11584 划分成回文串 线性dp
- uva11400照明系统设计与uva11584划分成回文串
- UVa 11584 划分回文串( 简单dp )
- Uva11584 最少回文串
- 【UVA 11584】【简单dp】Partitioning by Palindromes【给定一个字符串, 问最少分为几部分可使各部分均为回文串】
- uva11584 dp最少回文串划分
- uva 11584 把字符串分成最少的回文段
- UVA 11584 划分回文串
- Uva 11584,划分成回文串
- 动态规划(划分成回文串,uva 11584)
- uva 11584 划分回文串