合唱队

合唱队

http://www.nowcoder.com/questionTerminal/6d9d69e3898f45169a441632b325c7b4

这道题考的是常见的最长上升子序列问题。

#include <iostream>
using namespace std;

int main()
{
    int n;
    int m[10000], dp1[10000], dp2[10000];
    while(cin >> n)
    {
        for(int i = 0; i < n; i++)
        {
            cin >> m[i];
            dp1[i] = 1;
            for(int j = 0; j < i; j++)
            {
                if(m[i] > m[j]) dp1[i] = max(dp1[i], dp1[j]+1);
            }
        }
        for(int i = n-1; i >= 0; i--)
        {
            dp2[i] = 1;
            for(int j = n-1; j >= i; j--)
            {
                if(m[i] > m[j]) dp2[i] = max(dp2[i], dp2[j]+1);
            }
        }
        int mn = 0;
        for(int i = 0; i < n; i++)
        {
            if(dp1[i] + dp2[i] - 1 > mn) mn = dp1[i] + dp2[i] - 1;
        }
        cout << n-mn << endl;
    }
    return 0;
}

https://github.com/ultraji/nowcoder

全部评论
请问下解析中都说找最大递增字串中和最大递减字串中的位置,但题意中不是可以从中间抽人吗?那样最大的递增串可能是不连续中,中间抽掉两个反而最长呢?递增递减字串是连续的吧?
点赞 回复 分享
发布于 2020-02-21 14:50
#include<iostream> using namespace std; int main() { int n,a[10000],f[10000],f1[10000]; while(cin>>n){ for(int i=0;i<n;i++){//循环输入m[i] cin>>a[i]; f[i]=1;}//假设f[i]表述对应的a[i]中如果以a[i]作为最长上升子序列的最后一个数字,其中元素的个数 //赋值1的原因是:任何一个数字单独作为升子序列(以下简称序列)的最后一个数字的时候,元素个数为1。 for(int i=0;i<n;i++){//此时赋值已经完成, 即a[i]={a[0],a[1]...a[n]}。 for(int j=0;j<i;j++){//随意选取一个a[i],我们需要在它前面找满足条件: if(a[j]<a[i]){//条件即为a[j]<a[i],只有这样我们才能把a[j]保留在a[i]前面。 f[i]=max(f[j]+1,f[i]);}//假设原来我们采用的a[j]是序列的最后一个,对应一共有f[j]个元素,如果以a[i]作为序列最后一个,对应一共有f[i]个元素,由于a[j]<a[i],相当于a[j]作为序列尾元素的情况后又多了一个啊a[i] //那这个时候对应的new(新的)f[j]应该+1,而以a[i]作为序列尾元素,总体元素个数f[i]维持不变,取它们两个的最大值就是f[i]的实际值,因为是循环,,f[i] 可能赋过很多次值 ,因此需比较两者最大值得出序列成立是元素最多的情况。 } } for(int i=n-1;i>=0;i--){ f1[i]=1;//反向循环同理赋值。 for(int j=n-1;j>i;j--) { if(a[j]<a[i]){//反向循环找到a[i]右边的值满足a[j]<a[i],这样a[j]可以放在a[i]的右边,其他道理同上。 f1[i]=max(f1[j]+1,f1[i]);} } } int maxx=0;//这里就是定义它是满足要求的双向上升子序列中元素的个数。 for(int i=0;i<n;i++){ maxx=max(f[i]+f1[i]-1,maxx);}//当某个a[i]作为左->右循环尾值,一共有f[i]个元素,右->左循环首值,一共有元素f1[i]个,f[1]和f1[i]中均包含a[i]这个元素,所以最终元素个数要剪掉1个。 cout << n-maxx << endl;//总元素个数-剩下元素个数=踢出去的元素个数 } return 0; } //你是这个意思吧?
点赞 回复 分享
发布于 2020-02-28 20:18
是的
点赞 回复 分享
发布于 2020-02-29 10:01

相关推荐

09-29 17:44
已编辑
蔚来_测(准入职员工)
//鲨鱼辣椒:见不了了我实习了四个月上周再投筛选了一天就给我挂了
点赞 评论 收藏
分享
11-11 14:21
西京学院 C++
无敌混子大王:首先一点,不管学校层次怎么样,教育经历放在第一页靠上位置,第一页看不到教育经历,hr基本直接扔掉了
点赞 评论 收藏
分享
28 8 评论
分享
牛客网
牛客企业服务