This is a topic on the Leetcode, find out for a string, at least how many knives can make all the substring are palindrome string. The original question is https://oj.leetcode.com/problems/palindrome-partitioning-ii/
Given A string s, partition s such that every substring of the partition are a palindrome.
Return the minimum cuts needed for a palindrome partitioning of s.
For example, given s = "aab" ,
Return 1 since the palindrome partitioning ["aa","b"] could be produced using 1 cut.
This is a typical dynamic programming problem from the perspective of the topic. I see this topic immediately thinking fixed to the algorithm book to teach the matrix to multiply the minimum number of multiplication required problem. If the definition Dp[i][j] represents the minimum cut number between intervals [I,j], then its recursive relationship can be written
Dp[i][j] = min (Dp[i][k] + dp[k+1][j] + 1), I <= K < J. The code is easy to write.
classSolution { Public: intMincut (strings) {if(s.length () = =0||Ispalindr (s))return 0; Const intN =s.length (); intCuts[n][n]; for(intK =1; K <= N; k++){ for(inti =0; i + K-1< N; i++){ if(s[i]==s[i+k-1] && (k <=2|| cuts[i+1][i+k-2]==0)) Cuts[i][i+k-1] =0; Else{cuts[i][i+k-1] =Int_max; for(intj = i; J < i+k-1; J + +){ if(cuts[i][i+k-1] > Cuts[i][j] + cuts[j+1][i+k-1] +1) Cuts[i][i+k-1] = Cuts[i][j] + cuts[j+1][i+k-1] +1; } } } } returncuts[0][n-1]; } BOOLIspalindr (string&s) { if(s.length () = =0) return true; intleft =0, right = S.length ()-1; while(Left <=Right ) { if(s[left++]!=s[right--]) return false; } return true; }};
This is an O (n^3) algorithm, and the memory consumption is O (n^2), I commit when the memory allocation problem, then where can be optimized?
The above recursive relationship actually attempts to divide all the positions in I, J, and if [K+1, J] is not a palindrome, continue to divide [K+1, j] until all its substrings are palindrome strings, but we know that such a partition must have been tried at some K ' > K, Therefore, there is no need to continue to search in K, so when [K+1, J] is not a palindrome to skip directly. According to this idea, a one-dimensional dynamic programming can be constructed, using f[i] to represent the minimum number of cuts required from the n-1 to the first bit. First, F[i] is initialized to f[i] = n-1-i. I from n-1 to 0 loops, within each loop, the string inside the i~n-1 is scanned, each found a palindrome substring updated once the array, when the recurrence relationship is f[i] = min (f[i], f[j+1]+1), to ensure [I, j] is a palindrome substring.
classSolution { Public: intMincut (strings) {if(s.length () = =0) return 0; Const intN =s.length (); intcuts[n+1]; BOOLP[n][n]; Fill_n (&p[0][0], N*n,false); for(inti =0; I <= N; i++) {Cuts[i]= N-i-1; } for(inti = n1; I >=0; i--){ for(intj = i; J < N; J + +){ if(S[i]==s[j] && (J-i <2|| p[i+1][j-1])) {P[i][j]=true; Cuts[i]= Min (Cuts[i], cuts[j+1] +1); } } } returncuts[0]; } intMinintAintb) { return(A < b)?a:b; }};
Note
1. Many problems have dp[i][j] = min (Dp[i][k] + dp[k+1][j] + 1), I <= K < j form the recursive relationship, but some can continue to optimize for O (n^2), some cannot. The key question is whether the optimal partitioning is repetitive.
For the subject, the optimal division is likely to be repetitive. For example, the string s = "AABBBCCB", for K=1, S will be split into s1= "AA", s2 = "BBBCCB", and S2 will continue to be split into "BB" and "BCCB", the final split result is "AA", "BB" and "BCCB". For K=3, S will be split into "AABB" and "BCCB", and the final split result is still "AA", "BB" and "BCCB". Therefore, it is not necessary to continue to split the S2 when k=1, because the result of such splitting must have been considered elsewhere. A similar idea can be used to deal with a problem on the Hdoj http://acm.hdu.edu.cn/showproblem.php?pid=1227, the final optimal distribution in this problem is certainly satisfied for a i,i~n-1 restaurant from the same warehouse to supply.
For other problems, the optimal split may not be duplicated, such as the minimum number of multiplication required for multiple matrix multiplication. Different splits will eventually correspond to different computational processes, so the problem cannot be optimized with the above ideas.
2. The breakthrough of optimization is to reduce unnecessary computation, and different problems may have different forms of redundant computation. You need to think more and practise more to get acquainted.
[Leetcode] Palindrome Partitioning II