動態規劃——迴文串最小分割數
阿新 • • 發佈:2019-01-05
題目:
給定一個字串str,返回把str全部切成迴文子串的最小分割數。
舉例:
str="ABA" ,不需要切割,返回0;
str="ACDCDCDAD",最少需要切兩次,比如"A","CDCDC","DAD",所以返回2.
解題思路:動態規劃
狀態定義:
DP
[i]:表示子串(
0
,i)的最小回文切割數,則最優解在DP[s.length-
1
]中。(0,i)的子串中包括了i+1個字元,最多分割i次。
狀態轉移定義
:
1
.初始化:當字串str[0]--str[i]
(包括i位置的字元)是迴文時,DP[i] =
0
(表示不需要分割);否則,DP[i] = i(表示至多分割i次);
2
.對於任意大於
1
的i,如果str[j]--str[i]
( 1
<= j <= i ,即遍歷i之前的每個子串)是迴文時,DP[i] = min(DP[i], DP[j-
1
]+
1
);
(注:j不用取0是因為若j == 0,則又表示判斷(0,i))。
程式碼:
#include <string> #include <vector> #include <iostream> #include<algorithm> using namespace std; bool IsPalindrome(const char* str, int begin, int last)//判斷str[begin]--str[last]是否為迴文串 { int nbegin = begin; int nlast = last; while(nbegin<nlast) { if (str[nbegin]!=str[nlast]) return false; nbegin++; nlast--; } return true; } int main( ) { string strIn; cin>>strIn; int nlen = strIn.length(); vector<int> vecDP(nlen,0); for (int i=1;i<nlen;i++) { vecDP[i] = IsPalindrome(strIn.c_str(),0,i)?0:i;//初始化,若為迴文串則直接為0 for (int j=i;j>0;j--) { if (IsPalindrome(strIn.c_str(),j,i)) { vecDP[i] = min(vecDP[i],vecDP[j-1]+1);//狀態轉移 } } } cout<<vecDP[nlen-1];//輸出結果 return 0; }