例题9-7 划分成回文串 UVa11584
2015-02-13 12:56
288 查看
1.题目描述:点击打开链接
2.解题思路:本题要求划分回文串,且个数尽可能的少。可以用动态规划解决。先提前判断i~j是否构成回文串,时间复杂度是O(N^2),然后定义d(i)表示0~i-1划分成的回文串的最小个数。则状态转移方程为:
d(i)=min(d(i),d(j)+1)(s[j...i]是回文串)
上式中,d(i)的初始值是i,这样每次判断只需要O(1)的时间,总时间复杂度是O(N^2)。当然,判断回文串的过程可以和状态转移相结合,细节请参考第二份代码。
3.代码:
参考代码:
2.解题思路:本题要求划分回文串,且个数尽可能的少。可以用动态规划解决。先提前判断i~j是否构成回文串,时间复杂度是O(N^2),然后定义d(i)表示0~i-1划分成的回文串的最小个数。则状态转移方程为:
d(i)=min(d(i),d(j)+1)(s[j...i]是回文串)
上式中,d(i)的初始值是i,这样每次判断只需要O(1)的时间,总时间复杂度是O(N^2)。当然,判断回文串的过程可以和状态转移相结合,细节请参考第二份代码。
3.代码:
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<algorithm> #include<string> #include<sstream> #include<set> #include<vector> #include<stack> #include<map> #include<queue> #include<deque> #include<cstdlib> #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<functional> using namespace std; #define maxn 1030000 int vis[maxn]; int d[maxn]; int n; int main() { //freopen("test.txt", "r", stdin); cin >> n; while (n--) { string str; cin >> str; memset(vis, 0, sizeof(vis)); memset(d, 0, sizeof(d)); int len = str.length(); for (int i = 0; i <= len; i++)d[i] = i; for (int i = 0; i < 2 * len - 1; i++)//枚举中心,判断i到j是否为回文串 { int p; int m = i / 2; for (int j = m; j >=0; j--) { if (i - j<len&&str[j] == str[i - j]) { p = (j << 10) | (i - j); vis[p] = 1; } else break; } } int q = 0; for (int i = 0; i <= len; i++)//枚举起点,终点 { for (int j = 0; j <= i - 1; j++) { q = (j << 10) | (i - 1); if (vis[q]) d[i] = min(d[i], d[j] + 1); } } printf("%d\n", d[len]); } return 0; }
参考代码:
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<algorithm> #include<string> #include<sstream> #include<set> #include<vector> #include<stack> #include<map> #include<queue> #include<deque> #include<cstdlib> #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<functional> using namespace std; #define N 1002 int f ; bool d ; int main() { freopen("test.txt","r", stdin); int n, t, i, j, result; cin >> t; while (t--) { string s; cin >> s; n = s.length(); memset(f, 1000000, sizeof(f)); memset(d, false, sizeof(d)); for (int i = 0; i <= n; i++)//f[i]表示i到n划分成的最小回文串的个数 f[i] = n - i; for (int i = n - 1; i >= 0; i--)//i是起点,逆序枚举 for (int j = i; j < n; j++)//j是终点,顺序枚举 if (s[i] == s[j] && (j - i < 2 || d[i + 1][j - 1])) //如果j-i<2那么只需要直接用s[i]==s[j]判断即可,否则,用d[i+1][j-1]来判断是否为回文串 { d[i][j] = true; f[i] = min(f[i], f[j + 1] + 1); } cout << f[0] << endl; } return 0; }
相关文章推荐
- uva11584 划分成回文串
- UVa 11584 划分成回文串
- uva11584 划分成回文串
- UVA 11584 或 BNU20002 划分成回文串 DP求一个串最少能划分成多少个文回串
- uva 11584 划分成回文串
- 划分成回文串(uva 11584)
- UVA 11584 Partitioning by Palindromes 划分成回文串(DP + 预处理)
- UVA11584 划分成回文串
- uva 划分成回文串 11584 题解
- uva11584 划分成回文串 线性dp
- uva11400照明系统设计与uva11584划分成回文串
- 紫书动规 例题9-7 UVA - 11584 Partitioning by Palindromes dp
- uva 11584 Partitioning by Palindromes dp(最少回文串划分)
- Uva11584 最少回文串
- UVA 11584 划分回文串
- UVA-11584-Partitioning by Palindromes(区间DP 最小回文串数量)
- uva 11584 题目大意: 给一个字符串, 要求把它分割成若干个子串,使得每个子串都是回文串。问最少可以分割成多少个。
- uva 11584 把字符串分成最少的回文段
- 【算法竞赛入门经典】动态规划初步 例题9-7 UVa11584
- UVA 11584 Partitioning by Palindromes 划分回文串 (Manacher算法)