zoukankan      html  css  js  c++  java
  • 动态规划:最长递增子序列

    题目描述

    计算最少出列多少位同学,使得剩下的同学排成合唱队形

    说明:

    N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。
    合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK,   则他们的身高满足存在i(1<=i<=K)使得T1<T2<......<Ti-1<Ti>Ti+1>......>TK。
    你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。

    输入描述:

    整数N

    输出描述:

    最少需要几位同学出列

    输入

    8
    186 186 150 200 160 130 197 200
    

    输出

    4

    思路

    两遍最长递增子序列,第一遍从左往右,第二遍从右往左,然后把两遍动态规划的结果相加,取最大的那个,比如8 186 186 150 200 160 130 197 200,第一遍dp的结果是 1 1 1 2 2 1 3 4,第二遍dp的结果为3 3 2 3 2 1 1 1,那么相加最大是5,所以需要出列的同学个数就是8-5+1=4.代码如下:

     1 #include<iostream>
     2 #include<vector>
     3 using namespace std;
     4 int main() {
     5     int n;
     6     while(cin>>n){
     7         int max=0,temp;
     8         vector<int>queue,dp1(n,1),dp2(n,1);
     9         for(int i=0;i<n;++i){
    10             cin>>temp;
    11             queue.push_back(temp);
    12         }
    13         for(int i=0;i<n;++i)
    14             for(int j=i-1;j>=0;--j)
    15                 if(queue[i]>queue[j]&&dp1[i]<dp1[j]+1)
    16                     dp1[i]=dp1[j]+1;
    17         for(int i=n-1;i>=0;--i)
    18             for(int j=i+1;j<n;++j)
    19                 if(queue[i]>queue[j]&&dp2[i]<dp2[j]+1)
    20                     dp2[i]=dp2[j]+1;
    21         for(int i=0;i<n;++i){
    22             int cur=dp1[i]+dp2[i]-1;
    23             max=max>cur?max:cur;
    24         }
    25         cout<<n-max<<endl;
    26     }
    27     return 0;
    28 }
  • 相关阅读:
    保存ADO的记录集为XML文件
    [C++] Undefined reference to vtable
    Csdn博客的一个bug
    深入解析ATL(第二版ATL8.0)(1.111.13节)
    不同操作系统下记事本的换行符号
    dom4j学习总结(一)
    关于firefox的copy/paste的问题
    php URL编码解码函数
    php连接MySQL数据库的一些问题
    使用 jQuery progressBar 做文件上传的进度条指示
  • 原文地址:https://www.cnblogs.com/xiehuazhen/p/12371618.html
Copyright © 2011-2022 走看看