动态规划|删除最少的元素-最长下降子序列

删除最少的元素

给定有 nn 个数的 AA 序列:A_1,A_2,A_3\cdots A_nA?1??,A?2??,A?3???A?n??。对于这个序列,我们想得到一个子序列 A_{p_1}, A_{p_2} \cdots A_{p_i} \cdots A_{p_m}(1 \le p_1 < p_2<\cdots p_i < \cdots < p_m \le n)A?p?1????,A?p?2?????A?p?i?????A?p?m????(1≤p?1??<p?2??<?p?i??<?<p?m??≤n),满足 A_{p_1} \ge A_{p_2} \ge \cdots \ge A_{p_i} \le \cdots \le A_{p_m}A?p?1????≥A?p?2????≥?≥A?p?i????≤?≤A?p?m????。从 AA 序列最少删除多少元素,可以得到我们想要的子序列。

输入格式
第一行输入一个整数 nn,代表 AA 序列中数字的个数。第二个输入 nn 个整数,代表A_1,A_2,A_3...A_nA?1??,A?2??,A?3??...A?n??。

(1 \leq n \leq 10001≤n≤1000,1 \leq A_i \leq 100001≤A?i??≤10000)

输出格式
输出需要删除的元素个数,占一行。

样例输入
7
3 2 4 1 2 5 3
样例输出
2

思路:分别正序dp一次,倒序dp一次。dp正序[i]+dp逆序[i]-1的最小值即所求结果。

#include<iostream>
#include<algorithm>
using namespace std;

const int MAX_N = 1010;
int n;
int a[MAX_N];
int dp1[MAX_N];
int dp2[MAX_N];

int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }

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

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

    int ans = 0;
    for(int i=1;i<=n;i++){
        ans = max(ans,dp1[i] + dp2[i] -1);
    }
    cout<<n-ans<<endl;
    return 0;
} 

原文地址:https://www.cnblogs.com/fisherss/p/10316401.html

时间: 2024-11-08 06:23:34

动态规划|删除最少的元素-最长下降子序列的相关文章

动态规划|蒜头君跳木桩-最长下降子序列

蒜头君跳木桩 蒜头君面前有一排?nn?个木桩,木桩的高度分别是h_1,h_2,h_3\cdots h_nh1?,h2?,h3??hn?.蒜头第一步可以跳到任意一个木桩,接下来的每一步蒜头不能往回跳只能往前跳,并且跳下一个木桩的高度?不大于?当前木桩.蒜头君希望能踩到尽量多的木桩,请你帮蒜头计算,最多能踩到多少个木桩. 输入格式 第一行输入一个整数?nn?代表木桩个数.第二行输入?nn?个整数?h_1,h_2,h_3\cdots h_nh1?,h2?,h3??hn?,分别代表?nn?个木桩的高度.

【最长下降子序列】【动态规划】【二分】XMU 1041 Sequence

题目链接: http://acm.xmu.edu.cn/JudgeOnline/problem.php?id=1041 题目大意: 一个二维平面,上面n(n<=1 000 000)个点.问至少选多少个点才能完全包含所有的点. 包含是指xy坐标均不大于. 题目思路: [最长下降子序列][动态规划][二分] 这题n有107,所以用二分做最长下降子序列. 首先将所有点按x坐标或者y坐标排序,保证一维的单调性. 之后在剩余一维的数中求最长严格下降子序列即可. (如果下一个点是上升的那么可以放弃当前的点转

HDU 1160 FatMouse&#39;s Speed (动态规划、最长下降子序列)

FatMouse's Speed Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 24573    Accepted Submission(s): 10896Special Judge Problem Description FatMouse believes that the fatter a mouse is, the faster

低价购买 (动态规划,变种最长下降子序列(LIS))

题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它.买的次数越多越好!你的目标是在遵循以上建议的前提下,求你最多能购买股票的次数.你将被给出一段时间内一支股票每天的出售价(216范围内的正整数),你可以选择在哪些天购买这支股票.每次购买都必须遵循“低价购买:再低价购买”的原则.写一个程序计算最大购买次数. 这里是某支股票的价格清单: 日期  1 

导弹拦截(最长下降子序列)变形

题目描述 Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹来袭.由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹. 输入描述 Input Description 输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数) 输出描述 Output Description 输出这套系统最多能拦截多少导弹

(hdu step 3.2.4)FatMouse&#39;s Speed(在第一关键字升序的情况下,根据第二关键字来求最长下降子序列)

在写题解之前给自己打一下广告哈~..抱歉了,希望大家多多支持我在CSDN的视频课程,地址如下: http://edu.csdn.net/course/detail/209 题目: FatMouse's Speed Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1034 Accepted Submission(s): 526   Proble

最长下降子序列O(n^2)及O(n*log(n))解法

求最长下降子序列和LIS基本思路是完全一样的,都是很经典的DP题目. 问题大都类似于 有一个序列 a1,a2,a3...ak..an,求其最长下降子序列(或者求其最长不下降子序列)的长度. 以最长下降子序列为例 用a[i]存储序列a的第i个元素(i: 1 to n) 用f[i]表示算上第i个位置的元素时最长子序列为f[i], O(n^2)解法: 就是说在1 --- i -1之间必可以找到下标为j的元素a[j]使得f[j]是f[1]---f[i-1]之中最大的,则f[i] = f[j] + 1.

BUY LOW, BUY LOWER_最长下降子序列

Description The advice to "buy low" is half the formula to success in the bovine stock market.To be considered a great investor you must also follow this problems' advice: "Buy low; buy lower" Each time you buy a stock, you must purcha

HDU - 6197 array array array (最长上升子序列&amp;最长下降子序列)

题意:对于一个序列,要求去掉正好K个数字,若能使其成为不上升子序列或不下降子序列,则“A is a magic array.”,否则"A is not a magic array.\n". 分析: 1.求一遍LCS,然后在将序列逆转,求一遍LCS,分别可得最长上升子序列和最长下降子序列的长度tmp1.tmp2. 2.n - tmp1 <= k或n - tmp2 <= k即可,需要去掉的去完之后,在已经是最长上升或最长下降的序列中随便去够k个就好了. #include<