(区间dp最长上升子序列,最长下降子序列)

简介: (区间dp最长上升子序列,最长下降子序列)

思路

特征 求一个最长的序列,中间值前面上升,后面下降

// 然后就可以拆分成以中间值为结尾的最长上升子序列和以中间值为开头的最长下降子序列,分别求后再加在一起即可。

需要注意的是,求得的和需要减一,因为中间值被重复加了两次,长度多了1

题解妙在将题目数组的状态以特殊点为边界,拆解成了两个dp子问题。

套路

以i结尾的最长连续上升子序列

for(int i = 1;i <= n;i++){
  f[i] = 1;
  for(int j = 1;j < i;j++){
    if(a[i] > a[j])
      f[i] = max(f[i],f[j]+1);
  }
}

以i开头的最长连续上升子序列

for(int i = n;i;i--){
  f[i] = 1;
  for(int j = n;j > i;j--){
    if(a[i] < a[j])
      f[i] = max(f[i],f[j]+1);
  }
}

以i结尾的最长连续下降子序列

for(int i = 1;i <= n;i++){
  f[i] = 1;
  for(int j = 1;j <= n;j++){
    if(a[i] < a[j])
      f[i] = max(f[i],f[j]+1);
  }
}

以i开头的最长连续下降子序列

for(int i = n;i;i--){
  f[i] = 1;
  for(int j = n;j > i;j--){
    if(f[i] > f[j])
      f[i] = max(f[i],f[j]+1);
  }
}

注意到以i结尾时,写法变为从1到n

for(int i = 1;i <= n;i++)
for(int j = 1;j < i;j++)

以i开头时,写法则变为从n到1

for(int i = n;i;i--)
for(int j = n;j > i;j--);

求以i结尾最长上升子序列时,写法变为

if(a[i] > a[j])

求以i开头最长上升子序列时,写法变为

if(a[i] < a[j])

求以i结尾最长下降子序列时,写法变为

if(a[i] < a[j])

求以i开头最长下降子序列时,写法变为

if(a[i] > a[j])
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
const int N = 110;
int f[N],cnt[N],a[N];
int main(){
    int n;
    cin >> n;
    for(int i = 1;i <= n;i++) cin >> a[i];
    for(int i = 1;i <= n;i++){
        f[i] = 1;
        for(int j = 1;j < i;j++) if(a[j] < a[i]) f[i] = max(f[j]+1,f[i]);
        cnt[i] += f[i];
    }
    for(int i = n;i;i--){
        f[i] = 1;
        for(int j = n;j > i;j--) if(a[j] < a[i]) f[i] = max(f[j] + 1,f[i]);
        cnt[i] += f[i] -1 ;
        // cout << cnt[i] << " " ;
    }
    int res = 0x3f3f3f3f;
    for(int i= 1;i <= n;i++){
        // cout << cnt[i] << " " ;
        res = min(n-cnt[i],res);
    }
    cout << res << endl;
    return 0;
}
目录
相关文章
|
6月前
|
机器学习/深度学习 算法 测试技术
【动态规划】【最长子序列】2901. 最长相邻不相等子序列 II
【动态规划】【最长子序列】2901. 最长相邻不相等子序列 II
【动态规划刷题 15】最长定差子序列&& 最长的斐波那契子序列的长度
【动态规划刷题 15】最长定差子序列&& 最长的斐波那契子序列的长度
【动态规划刷题 14】最长递增子序列的个数&& 最长数对链
【动态规划刷题 14】最长递增子序列的个数&& 最长数对链
|
算法 JavaScript Go
【动态规划】最长递增子序列
【动态规划】最长递增子序列
|
11月前
|
算法 程序员 C#
C++二分查找算法的应用:最长递增子序列
C++二分查找算法的应用:最长递增子序列
|
6月前
|
算法 程序员 索引
【算法训练-动态规划 三】【双序列DP问题】最长重复子数组、最长公共子串、最长公共子序列、编辑距离
【算法训练-动态规划 三】【双序列DP问题】最长重复子数组、最长公共子串、最长公共子序列、编辑距离
103 0
|
算法
【学会动态规划】最长递增子序列的个数(28)
【学会动态规划】最长递增子序列的个数(28)
43 0
|
算法
【学会动态规划】 最长递增子序列(26)
【学会动态规划】 最长递增子序列(26)
42 0
线性DP:最长上升(下降)子序列
线性DP:最长上升(下降)子序列
44 0
深入理解动态规划算法 - 最长公共子序列
深入理解动态规划算法 - 最长公共子序列
76 0