• 【Codeforces 1370-D】Odd-Even Subsequence 二分+贪心


    D. Odd-Even Subsequence

    题意

    给出一个数组 a ,让你选择一个 a 的子序列,使得 (min(max(a_1,a_3,a_5...),max(a_2,a_4,a_6...))) 最小。

    即奇数位置的最大值和偶数位置的最大值 的最小值最小。

    思路

    其实做这道题我还是很懵逼的,因为如果从选数的角度考虑的话,该选那些数字?这个问题不好解决。

    后来我想了枚举每个值作为答案的时候,是否合法,这样复杂度比较高,这时就想到了二分。

    把原数组排序,设 l = 1,r = n,二分结果分别从奇数,偶数中诞生,为 arr[mid] 是否合法。

    怎么检验合法呢?

    假如当前二分的是奇数作为答案,首先我们从头开始选,如果这个值小于等于 x (当前二分的答案值),那么把它放到当前选择的奇数当中,这时下一个能选择的距离这个值的距离要大于 1 。就这样选择下去,最后看剩余的数字最大值是不是大于等于 x。

    我写完之后突然意识到我没有判断 x 有没有被选择到奇数队列中,因为我们是把 x 作为奇数的最大值,那就要保证 x 要在奇数中,这样一来,竟然不知道该如何检验合法性。便放弃了二分的想法。(其实一直二分下去就对了,不在,说明这个 x 不是最佳答案,我没考虑好)

    后想了一个贪心的想法,假如答案在奇数产生,我们只需要保证奇数的所有值尽可能的小。

    按照他们的大小把下标进行排序,一次进行选择,如果当前数字的邻居并没有被选择,那么当前数字可以选择。

    最后根据判断奇数和偶数产生的答案,输出较小值。Wa6了。

    看了一下之前是因为代码写错了wa6了,最后wa9 是因为这样找可能根本找不到满足条件的序列。

    题解

    直接二分答案,l = 0,r = 1e9 。

    这样不用考虑当前二分的 x 在不在当前队列中,不在说明 x 不是最小值 ,继续二分就可以了。

    检验的时候检验是否可以找到一个长度为 k 的队列。

    看代码理解

    #include<bits/stdc++.h>
    #define pb push_back
    const int N=1e6+10;
    const int inf=0x3f3f3f3f;
    typedef long long ll;
    typedef unsigned long long ull;
    using namespace std;
    
    int arr[N],n,k;
    int check(int x,int m)
    {
        int num=0;
        for(int i=1; i<=n; i++)
        {
            if(arr[i]<=x||num%2==m)
                num++;
        }
        return num>=k;
    }
    int main()
    {
        scanf("%d%d",&n,&k);
        for(int i=1; i<=n; i++)
            scanf("%d",&arr[i]);
        int l=0,r=1e9,ans;
        while(l<=r)
        {
            int mid=(l+r)/2;
            if(check(mid,0)||check(mid,1))
            {
                ans=mid;
                r=mid-1;
            }
            else
                l=mid+1;
        }
        printf("%d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    Java SE 第十一讲(面向对象之封装)续二
    Java SE 第二十六讲 包与导入语句剖析
    Java SE 第三十一,二,三 Java数组剖析,Java数组内存地址解析
    Java SE 第三十四,五,六讲 Array类解析及数组疑难剖析,冒泡排序,交换排序以及快速排序
    Java SE 第三十八,九,四十,四十一,四十二,三四IDE详细介绍,ArrayList源代码深入剖析,L
    java高效的获取指定的精度的double数
    C++ 字符常量
    C++ endl
    C++基本数据类型
    vs2005的treeview简单使用之无限级别菜单建立
  • 原文地址:https://www.cnblogs.com/valk3/p/13299660.html
Copyright © 2020-2023  润新知