题目链接:http://codeforces.com/contest/798/problem/D
题目大意:
给两个数组,挑选n / 2 + 1个下标,使得a数组对应下标的和的两倍大于a数组的数之和,b数组对应下标的和的两倍大于b数组的数之和。拿到题目想不到如何贪心才是最优的。。于是偷看了大神题解。
将两个数组拼在一起排序,按照a数组从大到小排序,先选择第一个,然后后面开始每两个,每次选择b数组中大的那个,如果最后是偶数的话,再选择最后一个。
考虑这样贪心为何是最优的:首先,b数组里选择了第一个,后面的每一个都是选择比较大的,所以肯定所选下标的总和是大于数组总和的。其次a数组里第一次开始选择的是第一个,假设后面每次选的都是后一个,也能满足从下标0开始,每次递增2个位置,每次i比i+1要大。所以该贪心是成立的orz。感觉很久不会贪心了。
附上代码:
/*
@resources: codeforces 798d
@date: 2017-4-27
@author: QuanQqqqq
@algorithm: greedy
*/
#include <bits/stdc++.h>
#define MAXN 100005
#define INF 1e10
using namespace std;
struct node{
int a,b,idx;
}num[MAXN];
int cmp(node a,node b){
return a.a > b.a;
}
int main(){
int n;
scanf("%d",&n);
for(int i = 0;i < n;i++){
scanf("%d",&num[i].a);
}
for(int i = 0;i < n;i++){
scanf("%d",&num[i].b);
num[i].idx = i + 1;
}
sort(num,num + n,cmp);
printf("%d\n",n / 2 + 1);
printf("%d",num[0].idx);
for(int i = 1;i + 1 < n;i += 2){
if(num[i].b > num[i + 1].b){
printf(" %d",num[i].idx);
} else {
printf(" %d",num[i + 1].idx);
}
}
if(n % 2 == 0){
printf(" %d\n",num[n - 1].idx);
}
}