【NOIP2004】合唱队形

本题在洛谷上的链接:https://www.luogu.org/problemnew/show/P1091


 

水题。。。没啥好说的,求一遍正向的最长上升子序列和一遍逆向的最长上升子序列就可以了。

唯一需要注意的是,求最长上升子序列之类的那种O(n^2)算法中,定义dp[i]是指以第i个元素为结尾的最长上升子序列长度,而O(nlogn)算法中,是指考虑到第i个元素所能产生的最长上升子序列长度,如果要使用O(nlogn)的做法,需要维护以当前元素结尾的最长上升子序列。但是,,,这题的范围也太小了,我写的O(nlogn)的做法咋还没O(n^2)快呢!!!

 1 #include <cstdio>
 2 #include <algorithm>
 3 
 4 using namespace std;
 5 
 6 const int maxn = 105;
 7 
 8 int h[maxn], dp[maxn], up[maxn];
 9 
10 int main() {
11     int n, len = 0, ans = 0;
12     scanf("%d", &n);
13     for (int i = 1; i <= n; ++i) {
14         scanf("%d", &h[i]);
15         if (h[i] > dp[len]) dp[++len] = h[i], up[i] = len;
16         else {
17             int pos = lower_bound(dp + 1, dp + len + 1, h[i]) - dp;
18             dp[pos] = h[i], up[i] = pos;
19         }
20     }
21     len = 0;
22     for (int i = n; i >= 1; --i) {
23         int down = 0;
24         if (h[i] > dp[len]) dp[++len] = h[i], down = len;
25         else {
26             int pos = lower_bound(dp + 1, dp + len + 1, h[i]) - dp;
27             dp[pos] = h[i], down = pos;
28         }
29         if (ans < up[i] + down) ans = up[i] + down;
30     }
31     printf("%d", n - ans + 1);
32     return 0;
33 }
AC代码

 

转载于:https://www.cnblogs.com/Mr94Kevin/p/9599732.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值