Odd-Even Subsequence

题目链接
题意:
给定一个大小为n的数组a,要求找到一个长度为k的子序列s,使得这个子序列的成本最小。这里提到的“成本”定义为:对于子序列s中奇数位置上的所有元素取最大值,以及对于偶数位置上的所有元素取最大值,然后取这两个最大值中的较小者作为该子序列的成本。
思路:
二分答案,考虑如何check mid,check时考虑贪心,考虑奇数时最大值小于等于mid,如果不行再考虑偶数。时间复杂度O(nlogn),具体实现见代码。

点击查看代码
// #pragma GCC optimize("O3")
// #pragma G++ optimize("O3")
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
#define ll long long 
#define itn int
const int N = 2e5+5;
int arr[N];
int n,k;
bool ok(int x){
    itn g=0;
    int ji,ou,jiend,ouend;
    if(k&1){
        ji=k/2+1,ou=ji-1,jiend=n,ouend=n-1;
    }else{
        ou=ji=k/2,jiend=n-1,ouend=n;
    }
    for(int i=1;i<=jiend;){
        if(arr[i]<=x){
            g++;
            i+=2;
            if(g==ji){
                return 1; //奇数满足则返回true
            }
        }else{
            i++;
        }
    }
    g=0;
    for(int i=2;i<=ouend;){
        if(arr[i]<=x){
            g++;
            i+=2;
            if(g==ou){
                return 1; //偶数满足返回true
            }
        }else{
            i++;
        }
    }
    return 0; //奇偶都不满足,返回false
}
void solve(){
    cin>>n>>k;
    int zuida=0;
    int zuixiao=1e9+4;
    for(int i=1;i<=n;++i){
        cin>>arr[i];
        zuida=max(zuida,arr[i]);
        zuixiao=min(zuixiao,arr[i]);
    }
    int l=zuixiao,r=zuida;
    while(r-l>5){
        int mid=(l+r)>>1;
        if(ok(mid)){
            r=mid;
        }else{
            l=mid+1;
        }
    }
    for(int i=l;i<=r;++i){
        if(ok(i)){   
            cout<<i<<endl;
            return ;
        }
    }
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int _=1;
    // cin>>_;
    while(_--)
    solve();
    return 0;
}
posted @ 2025-02-21 18:43  sjgigj  阅读(12)  评论(0)    收藏  举报