题意:
给定两个数列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;
}
总结:
贪心:
先根据贡献极端地考虑,然后考虑约束条件,然后我们去考虑恰好(勉强)去满足这个约束条件