F.拿物品
题目链接-拿物品
解题思路
- 贪心,最优的策略就是自己多拿且让对方少拿
- 假设牛牛最后得分为N,牛可乐为M
- 如果 牛牛的一个物品与 牛可乐的一个物品交换,则 m=N−a1+a2,m=M+b1−b2
- 对于牛牛目标是最大化n-m,所以当n-m>N-M时会更优
可列不等式N-a1+a2-(M+b1-b2)>N-M,解得a2+b2>b1+b2 - 对于牛可乐也一样,所以两人都会优先选择 ai+bi 最大的物品
- 所以将物品按照ai+bi大小从小到大排序,两人依次选取即可
附上代码
- 结构体
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int INF=0x3f3f3f;
const int N=2e5+5;
typedef pair<int,int> PII;
struct node{
int c,id;
}s[N];
int a[N];
bool cmp(node x,node y){
return x.c>y.c;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
int n;
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
for(int i=0;i<n;i++){
int b;
cin>>b;
s[i].c=a[i]+b;
s[i].id=i+1;
}
sort(s,s+n,cmp);
for(int i=0;i<n;i+=2)
cout<<s[i].id<<" ";
cout<<endl;
for(int i=1;i<n;i+=2)
cout<<s[i].id<<" ";
cout<<endl;
return 0;
}
- vector
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 7;
int n; vector<int>sa, sb;
struct atom {
int a, b, id;
bool operator < (const atom &rhs) const {
return a + b > rhs.a + rhs.b;
}
} a[N];
int main() {
scanf("%d", &n);
assert(n >= 1 && n <= 200000);
for (int i = 1; i <= n; ++i) scanf("%d", &a[i].a);
for (int i = 1; i <= n; ++i) scanf("%d", &a[i].b), a[i].id = i;
sort(a + 1, a + 1 + n);
for (int i = 1; i <= n; ++i)
((i & 1) ? sa : sb).push_back(a[i].id);
for (auto x : sa) printf("%d ", x);
puts("");
for (auto x : sb) printf("%d ", x);
return 0;
}