Codeforces Round #820 (Div. 3) D. Friends and the Restaurant

该博客讨论了一种使用贪心策略解决数列选取问题的方法。给定两个数列x[i]和y[i],目标是找到最大的选取次数,使得选取的x[i]之和大于等于对应的y[i]之和,且选取的元素不重复。通过构造c[i]=x[i]-y[i]并排序,博主采用二分查找策略找到满足条件的最大数量的数对,从而实现最大选取次数的计算。代码中展示了具体的实现过程。
摘要由CSDN通过智能技术生成

Problem - D - Codeforces

题意:

给定两个数列x[i],y[i],每次操作你都能选取一些i,要求x[i]加起来必须大于等于y[i]加起来,且选的数必须大于等于两个,每次选取的i不能重复,求最大的选取的次数

思路:

贪心

要让选取次数最大,极端地想就是每次取两个,但是约束条件是x[i]加起来要大于等于y[i]加起来,

因此我们考虑构造一个c[i]=x[i]-y[i],这样c[i]就描述了差值,问题就变成了选取若干个c[i],约束条件是c[i]加起来要大于等于0,每次选取不能重复,问选取次数最多是多少。

那么贪心地考虑,因为给数列排个序不会有任何影响,因此我们先从小到大排个序。

我们每次取两个数,另一个数就是加起来刚好大于等于0的数,即我们取二分出第一个大于等于负a[r]的数即可,然后r--,去找别的对,然后计数

Code:

#include <bits/stdc++.h>
using namespace std;
const int mxn=1e5+10;
int n;
int a[mxn],b[mxn],c[mxn];
void solve(){
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++) cin>>b[i];
    for(int i=1;i<=n;i++) c[i]=b[i]-a[i];
    sort(c+1,c+1+n);
    int l=0,r=n,ans=0;
    while(l<r){
        l=lower_bound(c+l+1,c+1+n,-c[r])-c;
        if(l<r) ans++;
        r--;
    }
    cout<<ans<<endl;
}
int main(){
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int T;
    cin>>T;
    while(T--) solve();
    return 0;
}

总结:

贪心:

先根据贡献极端地考虑,然后考虑约束条件,然后我们去考虑恰好(勉强)去满足这个约束条件

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值