[luogu] P1020 导弹拦截

P1020 导弹拦截

题目详情
题目分析:一开始用的单调栈,后来发现不行,因为如果我们假设有这样的序列:

3 2 1 99 1

当遍历到99时,我们的栈会被我们自动清除,这时最后的最长不上升序列就只有3,而正确答案是4

upper_bound()返回有序序列中第一个大于查找值的指针。
lower_bound()返回有序序列中第一个大于等于查找值的指针。

思路

这道题只有o(nlogn)的算法才能得200分;

我们有一个栈,遍历导弹高度,如果导弹高度小于等于栈顶元素,就压入栈顶,如果大于,就在栈中二分查找第一个比这个高度小的元素并替换它。

为什么这样替换是正确的?

我们知道导弹只能按时间顺序打下来,不可能先打后面来的导弹,再打前面的导弹,那替换操作难道不会导致这样的情况吗?

我们知道只要这个元素不是栈顶元素,那这个元素永远都不会用到,因为我们的比较只跟栈顶元素有关,当我们替换一个元素的时候是不影响结果的,如果这时的导弹高度塞进去了,栈依然会保持有序。如果恰好这个导弹以后最长不上升序列比替换后的现有的序列要长,那后面的遍历中会一个一个的把现在的就序列换掉,最后变成一个更长的序列。而如果以后的最长不上升序列没有现在长,虽然中间有元素被替换了,但不影响原来的长度。

#include <cstdio>
#include <algorithm>
#include <functional>//greater的头文件
using namespace std;
int a[111111], num, sta1[111111], top, sta2[111111], topp;
int main()
{
    while (scanf("%d", &a[num]) != EOF) num++;
    sta1[top] = a[0];
    sta2[topp] = a[0];
    for (int i = 1; i < num; i++)
    {
        if (a[i] <= sta1[top]) sta1[++top] = a[i];
        else *upper_bound(sta1, sta1 + top, a[i], greater<int>()) = a[i];//upper_bound()返回指针取值直接修改原值,找到栈中第一个小于索引值的元素
        if (a[i] > sta2[topp]) sta2[++topp] = a[i];
        else *lower_bound(sta2, sta2 + topp, a[i]) = a[i];//找到第一个大于等于索引值的元素
    }
    printf("%d\n%d\n", top + 1, topp + 1);//栈是从0开始标的,所以加一。
}

这是o( n 2 n^2 )的算法。

#include <cstdio>
#include <algorithm>
using namespace std;
int a[111111], ans, num, an, sta1[111111], top, sta2[111111], topp;
int main()
{
    sta1[0] = 1;
    sta2[0] = 1;
    while (scanf("%d", &a[num]) != EOF)
        num++;
    for (int i = 1; i <= num - 1; i++)
    {
        int tem = 0;
        for (int j = 0; j < i; j++)
            if (a[i] <= a[j])
                if (tem < sta1[j])
                    tem = sta1[j];
        sta1[i] = tem + 1;
    }
    printf("%d\n", *max_element(sta1 + 1, sta1 + num));
    for (int i = 1; i <= num - 1; i++)
    {
        int tem = 0;
        for (int j = 0; j < i; j++)
            if (a[i] > a[j])
                if (tem < sta2[j])
                    tem = sta2[j];
        sta2[i] = tem + 1;
    }
    printf("%d\n", *max_element(sta2 + 1, sta2 + num));
}
发布了7 篇原创文章 · 获赞 0 · 访问量 66

猜你喜欢

转载自blog.csdn.net/weixin_45646006/article/details/105080943