概述
動態規劃提供了一種求最優問題的手段,本質上是通過合理的安排計算順序而避免重復計算。解決動態規劃問題主要在于2個方面:
- 尋找遞歸公式
- 確定計算順序
題目
Longest Palindromic Subsequence
典型動態規劃算法,遞推公式如下:
d[i][j]表示在(i, j) 里面最長的回文子串,存在如下遞推公式:
dp[i][j] =
dp[i+1][j-1] + 2, if s[i] == s[j]
max(dp[i][j-1], dp[i+1][j]), if s[i] != s[j]
只要按照確定的順序遍歷,即可得到答案。可以輔助畫一個二維數組圖來獲得遍歷順序, 可以發現按照如下順序遍歷可滿足減少重復計算需求:
遍歷順序示意圖
可以觀察到i, j的距離是從0~size-1變化,具體代碼如下:
class Solution {
public:
int longestPalindromeSubseq(string s) {
int dp[s.length()][s.length()];
memset(dp, 0, sizeof(int)* s.length() * s.length());
int i, j;
for (int dis = 0; dis < s.length(); ++dis) {
for (i = 0; (j = i + dis) < s.length(); ++i) {
if (dis == 0) {
dp[i][j] = 1;
}
else if (s[i] == s[j]) {
dp[i][j] = dp[i + 1][j - 1] + 2;
}
else {
dp[i][j] = max(dp[i+1][j], dp[i][j-1]);
}
}
}
return dp[0][s.length()-1];
}
};