Java教程

OpenJudge 2711 合唱队形

本文主要是介绍OpenJudge 2711 合唱队形,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

题目链接:OpenJudge 2711 合唱队形

题目大意:

题解:
正反各求一次最长上升序列,对每个点取正反两次以该点为最高点的最长上升子序列长度之和(注意该点被取两次,需要减一)即为以该点为最高点的最长合唱队列。

#include <algorithm>
#include <iostream>
using namespace std;
#define N 110

int n, dp1[N], dp2[N], h[N], t1[N], t2[N], len1, len2, ans;

int main() {
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> h[i];
    }
    dp1[++len1] = h[1];
    t1[1] = 1;
    for (int i = 1; i <= n; ++i) {
        if (dp1[len1] < h[i]) {
            dp1[++len1] = h[i];
            t1[i] = len1;
        } else {
            int p1 = lower_bound(dp1 + 1, dp1 + len1 + 1, h[i]) - dp1;
            dp1[p1] = h[i];
            t1[i] = p1;
        }
    }
    dp2[++len2] = h[n];
    t2[n] = 1;
    for (int i = n; i > 0; --i) {
        if (dp2[len2] < h[i]) {
            dp2[++len2] = h[i];
            t2[i] = len2;
        } else {
            int p2 = lower_bound(dp2 + 1, dp2 + len2 + 1, h[i]) - dp2;
            dp2[p2] = h[i];
            t2[i] = p2;
        }
    }
    for (int i = 1; i <= n; ++i) {
        ans = max(ans, t1[i] + t2[i] - 1);
    }
    cout << n - ans;
    return 0;
}
这篇关于OpenJudge 2711 合唱队形的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!