uva 划分成回文串 11584 题解
2015-05-01 12:42
281 查看
题目大意是求把一字符串划分成尽可能少的回文串,用dp来做
状态转移方程是d[i]=min{d[j]+1}其中j+1到i为回文串
问题的关键在于如果每次转移都要判断j+1到i是不是回文串,那么时间复杂度将达到状态o(n)*决策o(n)*每次转移判断o(n),也就是o(n^3),所以预处理判断str【i】到str【j】是否为回文串,则复杂度可降到o(n^2)
源码如下
状态转移方程是d[i]=min{d[j]+1}其中j+1到i为回文串
问题的关键在于如果每次转移都要判断j+1到i是不是回文串,那么时间复杂度将达到状态o(n)*决策o(n)*每次转移判断o(n),也就是o(n^3),所以预处理判断str【i】到str【j】是否为回文串,则复杂度可降到o(n^2)
源码如下
#include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<algorithm> #include<vector> #include<map> #include<queue> #include<stack> #include<string> using namespace std; #define LL long long const int maxn=1005; string str; int h[maxn][maxn],d[maxn]; int main(){ int t; cin>>t; while(t--){ cin>>str; int n=str.length(); //printf("%d\n",n); memset(h,0,sizeof(h)); for(int i=0;i<n;i++){ for(int j=0;i-j>=0&&i+j<n;j++) if(str[i-j]==str[i+j]) h[i-j][i+j]=1; else break; } for(int i=0;i<n-1;i++){ for(int j=0;i-j>=0&&i+j+1<n;j++){ if(str[i-j]==str[i+j+1]) h[i-j][i+j+1]=1; else break; } } for(int i=0;i<n;i++){ d[i]=i+1; //printf("%d\n",d[i]); if(h[0][i]){ d[i]=1; continue; } //printf("%d\n",d[i]); for(int j=1;j<=i;j++) if(h[j][i]) d[i]=min(d[j-1]+1,d[i]); else d[i]=min(d[j-1]+i-j+1,d[i]); //printf("%d\n",d[i]); } cout<<d[n-1]<<endl; } return 0; }
相关文章推荐
- uva11584 划分成回文串 线性dp
- uva11400照明系统设计与uva11584划分成回文串
- 划分成回文串(uva 11584)
- UVA11584 划分成回文串
- 例题9-7 划分成回文串 UVa11584
- UVa 11584 划分成回文串
- uva11584 划分成回文串
- UVA 11584 Partitioning by Palindromes 划分成回文串(DP + 预处理)
- UVA 11584 或 BNU20002 划分成回文串 DP求一个串最少能划分成多少个文回串
- uva 11584 划分成回文串
- uva11584 划分成回文串
- UVA 11584 Partitioning by Palindromes 划分回文串 (Manacher算法)
- uva 11584 划分回文串
- Uva11584 最少回文串
- UVA-11584-Partitioning by Palindromes(区间DP 最小回文串数量)
- UVa 11584 划分回文串( 简单dp )
- 【UVA 11584】【简单dp】Partitioning by Palindromes【给定一个字符串, 问最少分为几部分可使各部分均为回文串】
- UVA-11584 Partitioning by Palindromes 动态规划 回文串的最少个数
- uva11584 dp最少回文串划分
- uva 11584 把字符串分成最少的回文段