動態規劃例題2:刪除最少的子元素
阿新 • • 發佈:2018-12-17
給定有n個數的A序列:A1,A2,A3,....An,對於這個數列,我們想得到一個子序列Ap1,Ap2...Api....Apm
滿足Ap1 >= Ap2>=Api <=....<=Apm
從A中刪除多少元素,可以得到我們所需的子序列
輸入
7
3 2 4 1 2 5 3
輸出
2
解題思路,我們可以通過動態規劃演算法,從左到右得到各個子序列的上升子序列元素個數(用dp儲存狀態)
從右到左得到各個子序列的下降子序列個數(也用一個dp儲存狀態)
最後將每個狀態相加,排序得到最大的那個狀態
實現程式碼如下:
#include <iostream> #include <vector> using namespace std; int countDeletedElements(vector<int> &nums) { int dp1[1001] = { 0 }; int dp2[1001] = { 0 }; //從左到右遞減子序列 for (int i = 0; i < nums.size(); ++i) { dp1[i] = 1; for(int j = 0; j < i; ++j) { if (nums[j] >= nums[i]) { dp1[i] = max(dp1[i], dp1[j] + 1); } } } //從右到左遞增 for (int i = nums.size() - 1; i >= 0; --i) { dp2[i] = 1; for (int j = nums.size() - 1; j > i; --j) { if (nums[j] >= nums[i]) { dp2[i] = max(dp2[i], dp2[j] + 1); } } } //單個點進行比較列舉 int temp = 0; for (int i = 0; i < nums.size(); ++i) { if (dp1[i] + dp2[i] > temp) { temp = dp1[i] + dp2[i]; } } return nums.size() - temp + 1; } int main() { int n; vector<int> a; cin >> n; for (int i = 0; i < n; ++i) { int d; cin >> d; a.push_back(d); } cout << countDeletedElements(a) << endl; return 0; }