题解 | #合唱队#

合唱队

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

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

int main() {
    int n,maxlen=0;
    cin>>n;
    vector<int> v(n),dp1(n,1),dp2(n,1);
    for(int i=0;i<n;++i)cin>>v[i];
    for(int i=1;i<n;++i){
        for(int j=0;j<i;++j){// 记录左侧
            if(v[j]<v[i]){
                dp1[i]=max(dp1[i],dp1[j]+1);
            }
        }
    }
    for(int i=n-2;i>=0;--i){
        dp2[i]=1;
        for(int j=n-1;j>i;--j){// 记录右侧
            if(v[j]<v[i]){
                dp2[i]=max(dp2[i],dp2[j]+1);
            }
        }
    }
    for(int i=0;i<n;i++){
        if(dp1[i]+dp2[i]-1>maxlen)maxlen=dp1[i]+dp2[i]-1;
    }
    cout<<n-maxlen<<endl;
}

思路:

将问题抽象为:寻找队列中”最大“的中间数,每一个数可以看作一个单个"合唱队"。对每一个数对应两个参数:左边递减的数、右边递减的数。在依次遍历完成后,寻找左右参数之和最大的数(根据自己实际代码要注意是否需要减1),即为合唱队最多人数。

算法:动态规划(时间复杂度O(n^{2})

以我个人看来,这道题无疑是动态规划的入门最佳题。从问题拆分到历史数据记录都能有所体现,而且在历史数据记录的问题上可以从for循环的方向选择中有所体现。换个说法就是从0向n-1遍历(++i)和从n-1向0遍历(--i)是不同的记录过程。具体的就多做两道题或者看看这道题解(思路很像的)合并表记录

春节怠慢了,后续会继续努力寻找有意思的题目分享

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务