[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 
 2 #include 
 3 #include 
 4 #include 
 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 ****************************************************************/

 

转载于:https://www.cnblogs.com/easonliu/p/4461884.html

你可能感兴趣的:([Jobdu] 题目1500:出操队形)