动态规划(DP) 求回文划分
2018-03-29 20:26
197 查看
#include<iostream> #include <string> #include <vector> using namespace std; void CalcSubPalindrome(const string &str,int size,vector<vector<bool>>&p) { for (int i=0;i<size;i++) { p[i][i]=true; } for (int i=size-2;i>=0;i--) { p[i][i+1]=(str[i]==str[i+1]); for (int j=i+2;j<size;j++) { if ((str[i]==str[j])&&p[i+1][j-1]==true) { p[i][j]=true; } } } }/*DP 在(i+1,j-1)为回文串的前提下 str[i]==str[j] ->(i,j)为回文串 */ //DFS void MinPalindrome(const string str,int size,int nStart,const vector<vector<bool>>&p, vector<vector<string>>&all,vector<string>&solution) { if (nStart>=size) { all.push_back(solution); } for (int i=nStart;i<size;i++) { if (p[nStart][i]) //[nstart i]构成了回文子串 { solution.push_back(str.substr(nStart,i+1-nStart)); MinPalindrome(str,size,i+1,p,all,solution); solution.pop_back(); } } } void ADD(vector<vector<string>>&to,vector<vector<string>>&from,const string &sub) { if (from.empty()) { to.push_back(vector<string>(1,sub)); // } //to=from; for (vector<vector<string>>::const_iterator it=from.begin();it!=from.end();it++) { //to.push_back(vector<string>()); //vector<string>&now=to.back(); //引用 vector<string>now; for(vector<string>::const_iterator s=it->begin();s!=it->end();s++) { now.push_back(*s); } now.push_back(sub); to.push_back(now); } //for (int i = 0; i < from.size(); i++) //{ // for (int j=0;j<from[i].size();j++) // { // to[i].push_back(from[i][j]); // } // to[i].push_back(sub); //} } //DP void MinPalindrome2(const string str,int size,const vector<vector<bool>>&p, vector<vector<string>>&all) { vector<vector<string>>*prefix=new vector<vector<string>>[size]; //prefix[0].push_back(vector<string>(str[0])); prefix[0].clear(); for (int i=1;i<=size;i++) { for (int j=0;j<i;j++) { if (p[j][i-1]) { ADD((i==size)?all:prefix[i],prefix[j],str.substr(j,i-j)); } } } } void Print_Bool(const vector<vector<bool>>p,int size) { for (int i=0;i<size;i++) { for (int j=0;j<size;j++) { if(p[i][j]) cout<<"1"<<" "; else cout<<"0"<<" "; } cout<<endl; } } void Print_solution(vector<string>solution) { for (int i=0;i<solution.size();i++) { cout<<solution[i]<<"|"; } } void Print_all(const vector<vector<string>>all) { for (int i=0;i<all.size();i++) { Print_solution(all[i]); cout<<endl; } } int main() { string str="abacdccdaa"; int len=str.length(); vector<vector<bool>>p; p.resize(len); for (int i=0;i<len;i++) { p[i].resize(len); } CalcSubPalindrome(str,len,p); //Print_Bool(p,len); vector<vector<string>>all;//所有结果 MinPalindrome2(str,len,p,all); //vector<string> solution;// //MinPalindrome(str,len,0,p,all,solution); cout<<"Count:"<<all.size()<<endl; Print_all(all); //Print_Bool(p,len); return 0; }
Count:16
aba|c|dccd
4000
|aa|
a|b|a|c|dccd|aa|
aba|c|d|cc|d|aa|
a|b|a|c|d|cc|d|aa|
aba|cdc|c|d|aa|
a|b|a|cdc|c|d|aa|
aba|c|d|c|c|d|aa|
a|b|a|c|d|c|c|d|aa|
aba|c|dccd|a|a|
a|b|a|c|dccd|a|a|
aba|c|d|cc|d|a|a|
a|b|a|c|d|cc|d|a|a|
aba|cdc|c|d|a|a|
a|b|a|cdc|c|d|a|a|
aba|c|d|c|c|d|a|a|
a|b|a|c|d|c|c|d|a|a|
相关文章推荐
- (UVA - 11584) Partitioning by Palindromes(DP,划分的最小回文串个数)
- 动态规划学习系列——划分DP(二)
- UVA 10739 String to Palindrome (增删字符将非回文串串变身回文串,动态规划dp )
- Scau 8633 回文划分 mancher + dp
- 4000 集合的划分问题(动态规划DP)
- 动态规划学习系列——划分DP(三)
- HDU 1028 Ignatius and the Princess III(母函数 或者 整数划分的DP动态规划)
- 动态规划学习系列——划分DP(一)
- [OpenJudge8471][划分DP]切割回文
- 整数划分-划分数(DP动态规划)
- 夕拾算法进阶篇:16)最长回文子串(动态规划DP)
- 动态规划学习系列——数位DP(练手一)
- POJ 3280 Cheapest Palindrome(DP 回文变形)
- nyoj 整数划分(四) 746 (区间DP)
- 51NOD中的矩阵取数问题(1083,1084,1411)——动态规划,插头dp
- LeetCode(Palindrome partition 2) 求将一个字符串划分成回文子串 需要分成的段数最少是多少
- UVA 11552 Fewest Flops (序列划分DP,4级)
- leetcode 514. Freedom Trail 自由之路 + 旋转堆密码 + 动态规划DP解决
- POJ:1745 Divisibility(思维+动态规划DP)
- poj 3616 Milking Time ---DP(带权重的区间动态规划)