题解 | 合唱队形

#include <bits/stdc++.h>
using namespace std;

const int SIZE=100000;

int dp[SIZE];
int dp2[SIZE];

int main(){
    int n;
    while(cin>>n){
        memset(dp,INT_MIN,sizeof(dp));
        int a[n];
        for(int i=0;i<n;i++){
            cin>>a[i];
        }
        for(int i=0;i<n;i++){
            dp[i]=1;
            for(int j=0;j<i;j++){
                if(a[j]<a[i])dp[i]=max(dp[i],dp[j]+1);
            }
        }
        for(int i=n-1;i>=0;i--){
            dp2[i]=1;
            for(int j=n-1;j>i;j--){
                if(a[j]<a[i])dp2[i]=max(dp2[i],dp2[j]+1);
            }
        }

        int ans=1;
        for(int i=0;i<n;i++){
            if(dp[i]+dp2[i]>ans)ans=dp[i]+dp2[i];
        }
        cout<<n-ans+1<<endl;
    }
}

本题要找到两个方向上的最长段,可以知道,他要一个尖角,那么其实并不困难,只需要找到在 i 点往前和往后的最优删除即可,就利用我们的最优长度的计算方法,去找到两个最值,根据数学分析,可以知道n+1-两个的和,就是我们要的结果

全部评论
主要理解一个dp[i]的涵义及其应用,前面都是最大值,找一个最值是为了单项的最优,其实对于每个dp[i],都是当前的最优,不过注意是向左还是向右,因为这里生成了两个dp[]
点赞 回复 分享
发布于 01-10 16:42 河南

相关推荐

点赞 评论 收藏
分享
2024-12-30 10:54
大连理工大学 营销
龙吟风歌:不喜欢就立马换一份,不过公关类的和运营类的都比较杂......还是想清楚
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客企业服务