给定有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;
}