zoukankan      html  css  js  c++  java
  • [Jobdu] 题目1500:出操队形

    题目描述:

    在读高中的时候,每天早上学校都要组织全校的师生进行跑步来锻炼身体,每当出操令吹响时,大家就开始往楼下跑了,然后身高矮的排在队伍的前面,身高较高的就要排在队尾。突然,有一天出操负责人想了一个主意,想要变换一下队形,就是当大家都从楼上跑下来后,所有的学生都随机地占在一排,然后出操负责人从队伍中抽取出一部分学生,使得队伍中剩余的学生的身高从前往后看,是一个先升高后下降的“山峰”形状。据说这样的形状能够给大家带来好运,祝愿大家在学习的道路上勇攀高峰。(注,山峰只有一边也符合条件,如1,1、2,2、1均符合条件)

    输入:

    输入可能包含多个测试样例。
    对于每个测试案例,输入的第一行是一个整数n(1<=n<=1000000):代表将要输入的学生个数。
    输入的第二行包括n个整数:代表学生的身高(cm)(身高为不高于200的正整数)。

    输出:

    对应每个测试案例,输出需要抽出的最少学生人数。

    样例输入:
    6
    100 154 167 159 132 105
    5
    152 152 152 152 152
    样例输出:
    0
    4

    最长递增子序列问题的变型,从左找一遍,从右找一遍,再扫描一遍,找出dp1[i] + dp2[i]的最大值。最长递增子序列可以用二分查找优化成O(nlogn)的复杂度。手写了个二分找lower_bound的函数,也可以用STL里的。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <vector>
     4 #include <algorithm>
     5 using namespace std;
     6  
     7 int N;
     8 vector<int> v;
     9 vector<int> dp1, dp2;
    10 vector<int> st;
    11  
    12 void binSearch(int target) {
    13     if (st.empty() || target > st.back()) {
    14         st.push_back(target);
    15     } else {
    16         int l = 0, r = (int)st.size() - 1, m;
    17         while (l <= r) {
    18             m = l + ((r - l) >> 1);
    19             if (st[m] >= target) r = m - 1;
    20             else l = m + 1;
    21         }
    22         st[l] = target;
    23     }
    24 }
    25  
    26 void getDP() {
    27     st.clear();
    28     for (int i = 0; i < v.size(); ++i) {
    29         binSearch(v[i]);
    30         dp1[i] = st.size();
    31     }
    32     st.clear();
    33     for (int i = (int)v.size() - 1; i >= 0; --i) {
    34         binSearch(v[i]);
    35         dp2[i] = st.size();
    36     }
    37 }
    38  
    39 void solve() {
    40     getDP();
    41     int res = 0;
    42     for (int i = 0; i < N; ++i) {
    43         res = max(res, dp1[i] + dp2[i] - 1);
    44     }
    45     cout << N - res << endl;
    46 }
    47  
    48 int main() {
    49     while (scanf("%d", &N) != EOF) {
    50         v.resize(N);
    51         dp1.resize(N);
    52         dp2.resize(N);
    53         for (int i = 0; i < N; ++i) scanf("%d", &v[i]);
    54         solve();
    55     }
    56     return 0;
    57 }
    58 /**************************************************************
    59     Problem: 1500
    60     User: hupo250
    61     Language: C++
    62     Result: Accepted
    63     Time:1050 ms
    64     Memory:13244 kb
    65 ****************************************************************/
  • 相关阅读:
    KnockoutJS 3.X API 第五章 高级应用(4) 自定义处理逻辑
    KnockoutJS 3.X API 第五章 高级应用(3) 虚拟元素绑定
    KnockoutJS 3.X API 第五章 高级应用(2) 控制后代绑定
    KnockoutJS 3.X API 第五章 高级应用(1) 创建自定义绑定
    KnockoutJS 3.X API 第四章(14) 绑定语法细节
    KnockoutJS 3.X API 第四章(13) template绑定
    KnockoutJS 3.X API 第四章 表单绑定(12) selectedOptions、uniqueName绑定
    KnockoutJS 3.X API 第四章 表单绑定(11) options绑定
    KnockoutJS 3.X API 第四章 表单绑定(10) textInput、hasFocus、checked绑定
    KnockoutJS 3.X API 第四章 表单绑定(9) value绑定
  • 原文地址:https://www.cnblogs.com/easonliu/p/4461884.html
Copyright © 2011-2022 走看看