题解 | #合唱队#

合唱队

https://www.nowcoder.com/practice/6d9d69e3898f45169a441632b325c7b4

找到去除最少的人,也就是保留最多的人。该问题可以转化成为找某个位置的最长递增子序列和递减子序列问题。也就是之前做过的走桩子问题。可以使用动态规划来解决。

找最长递增子序列长度,可以使用动态规划设置dp数组记录各位置长度,从左往右依次遍历各位置i,对于i,找位于i之前位置中个子低于i的j,如果j记录的最长子序列大于i的长度,那么更新dp[i]为dp[j]+1。

同理,对于递减子序列,相当于反向递增子序列,从后往前依次遍历。使用dp2记录

最后每个位置最长子序列长度相当于dp1+dp2-1,减1是因为长度多记录了一次。

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



int main() {
    int num = 0;
    cin >> num;

    vector<int> store(num);
    for(int i = 0; i < num; i++) cin>>store[i];


    vector<int> dp1(num,0), dp2(num,0);

    // 从前往后,找每个同学的前向最长递减子序列
    for(int i = 0; i < num; i ++){
        dp1[i] = 1;
        for(int j = 0; j < i; j ++){
            if(store[i]>store[j]){
                dp1[i] = dp1[i]>dp1[j]+1?dp1[i]:dp1[j]+1;
            }
        }
    }

    // 从后往前,找每个同学的后向最长递减子序列
    for(int i = num-1; i >= 0; i --){
        dp2[i] = 1;
        for(int j = i+1; j < num; j ++){
            if(store[i]>store[j]){
                dp2[i] = dp2[i]>dp2[j]+1?dp2[i]:dp2[j]+1;
            }
        }
    }

    // 找到最大的同学使两子序列加和最大
    int max_len = 0;
    for(int i = 0; i < num; i++)
        max_len = max_len>dp1[i]+dp2[i]-1? max_len:dp1[i]+dp2[i]-1;
    
    cout << num-max_len << endl;
}
// 64 位输出请用 printf("%lld")

全部评论

相关推荐

bg27强双非本,目前在学习golang后端gin框架部分,在b站找了一个轮子项目敲了一下,技术栈是gin&nbsp;+&nbsp;gorm&nbsp;+&nbsp;mysql&nbsp;+&nbsp;redis。我目前的想法是这一个月学习408和go八股以及刷算法然后在12月找个寒假实习然后大三下开始准备考研。我是考研意愿比较强烈,想问一下我是应该all&nbsp;in其中一个方向吗,我感觉我实习对我考研来说也是没什么帮助的好像。
牛客28967172...:毕业工作,考研,考公是完全不同的方向。 99%的人拼尽全力也只能把一个做好(能做好都已经是佼佼者了,比如进进大厂,考985或者考公) 如果你确定要考研可以不用学任何就业技术框架,也不用实习经验,刷题背知识点就行,但注意必须考92院校起步,因为这个年代双非硕毕业后完全不如双非本(互联网行业),可以说双非硕在互联网就业完全是负收益
投递哔哩哔哩等公司10个岗位
点赞 评论 收藏
分享
牛客41406533...:回答他在课上学,一辈子待在学校的老教授用三十年前的祖传PPT一字一句的讲解,使用谭浩强红皮书作为教材在devc++里面敲出a+++++a的瞬间爆出114514个编译错误来学这样才显得专业
点赞 评论 收藏
分享
痛痛痛痛信灬:我小米都面完两个月了 八月底面完的,现在还是显示面试中,没有比我恐怖的
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务