Ural 1635. Mnemonics and Palindromes
2016-08-05 14:52
302 查看
Time limit: 1.0 second |
input | output |
---|---|
pasoib | 6 p a s o i b |
zzzqxx | 3 zzz q xx |
wasitacatisaw | 1 |
Problem Source: XIII Open USU Championship
Difficulty: 220 Printable
version Submit solution Discussion
(35)
My submissions All
submissions (5582) All accepted submissions (1624) Solutions
rating (1322)
给一个字符串,求最少可以分为多少个回文子串
代码:
#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define pi acos(-1.0) #define maxn (4000 + 50) #define mol 1000000009 #define inf 0x3f3f3f3f #define Lowbit(x) (x & (-x)) using namespace std; typedef long long int LLI; //dp[i]表示从0到i最少有多少回文子串,初始为最大值 //dp[i] = min(dp[j] + 1); //pre[i]存的是以i结尾的回文子串的首地址(下标) char str[maxn]; int dp[maxn]; int vis[maxn][maxn]; int pre[maxn]; void handle(int n) { //vis[i][j]表示从i到j是不是回文串 //依据原理:如果i到j不是回文的,那么i-1到j+1也不是回文的 for(int i = 0; i < n; i ++) { for(int j = 0;; j ++) {//这是以i为对称轴,左右分别延伸j长度的 if(i - j < 0) break; if(i + j >= n) break; if(str[i + j] != str[i - j]) break; vis[i - j][i + j] = true; } for(int j = 1;; j ++) {//这是以i和i+1中间为对称轴 if(i - j + 1 < 0) break; if(i + j >= n) break; if(str[i - j + 1] != str[i + j]) break; vis[i - j + 1][i + j] = true; } } } stack > asta; int main() { // freopen("in.txt", "r" , stdin); // freopen("out.txt", "w" , stdout); scanf("%s",str); int len = strlen(str); fill(dp,dp + maxn,inf); fill(pre,pre + maxn,-1); memset(vis,false,sizeof(vis)); handle(len); dp[0] = 1; for(int i = 0; i < len; i ++) { if(vis[0][i]) dp[i] = 1,pre[i] = 0; } for(int i = 0;i < len;i ++){ if(dp[i] == 1) continue; for(int j = 0;j < i;j ++){ if(vis[j + 1][i] && dp[i] > dp[j] + 1){ dp[i] = dp[j] + 1; pre[i] = j + 1; } } } printf("%d\n",dp[len - 1]); int p = pre[len - 1],e = len - 1; while(e != -1 && p != -1){ asta.push(pair(p,e)); e = p - 1; p = pre[e]; } while(!asta.empty()){ int x = asta.top().first; int y = asta.top().second; asta.pop(); for(int i = x;i <= y;i ++){ printf("%c",str[i]); } if(!asta.empty()) printf(" "); } return 0; }
相关文章推荐
- C++动态规划之最长公子序列实例
- C++动态规划之背包问题解决方法
- C#使用动态规划解决0-1背包问题实例分析
- 动态规划
- C++ 动态规划
- 动态规划解决背包问题的核心思路
- DP(动态规划) 解游轮费用问题
- 动态规划的用法——01背包问题
- 动态规划的用法——01背包问题
- 《收集苹果》 动态规划入门
- 《DNA比对》蓝桥杯复赛试题
- 《背包问题》 动态规划
- 自顶向下动态规划解决最长公共子序列(LCS)问题
- 01背包问题
- 初学ACM - 半数集(Half Set)问题 NOJ 1010 / FOJ 1207
- 关于爬楼梯的动态规划算法
- 动态规划 --- hdu 1003 **
- DP问题各种模型的状态转移方程
- 0-1背包解题过程
- 背包问题