CSUST 4006-你真的会树套树套树吗?(贪心|dp)

题目链接:http://acm.csust.edu.cn/problem/4006
博客园食用链接:https://www.cnblogs.com/lonely-wind-/p/13436097.html

Description

g a y gay 黄和 g a y gay 行在一次探险过程中,获得了 n n 颗宝石,第 i i 颗宝石有 a [ i ] a[i] 的价值。

为了公平起见,他们决定要尽可能的使得他们 2 2 个人所获得的宝石价值尽可能的接近。

但是他们有点懒,想让学弟学妹们帮帮他们,给他们一个分配方案。

你能帮帮他们吗?

Input
第一行输入一个整数 n n 2 n 1 e 5 2\leq n\leq 1e5 ,代表给定正整数的数量。
第二行输入 n n 个正整数 a 1 , a 2 , a 3 ( 1 a i ) a1,a2,a3\cdots (1\leq ai) 所有a[i]的和不超过 2 n 2 2 * n - 2

Output
每组数据输出一个长度为 n n 01 01 序列, 0 0 表示 g a y gay 黄所选, 1 1 表示 g a y gay 行所选。答案可能不唯一,输出任意满足要求的 01 01 序列即可。

Sample Input 1
6
1 5 1 1 1 1
Sample Output 1
010000

Sample Input 2
4
2 1 2 1
Sample Output 2
0011

emmm,本来说这题是个防AK来着。。。结果被我们乱搞成了签到题。。。

实际上我们如果能够注意到**a[i]总和不超过 2 n 2 2*n-2 **的话,那么我们就可以大胆地来一波贪心,因为,如果 a i a_i 总和小于等于 2 n 2 2*n-2 的话,那么一定有足够多的一来填补最大和次大的空缺,可以得出的是1的个数一定会超过 n 2 \frac{n}{2} ,那么大胆贪一波就是取一个最大的,取一个次大的,然后再取1来弥补中间的空缺就好了。

以下是AC代码:

#include <bits/stdc++.h>
using namespace std;

const int mac=1e5+10;

struct node
{
	int id,val;
	bool operator<(const node&a)const{
		return val<a.val;
	}
}a[mac];
int vis[mac];

int main(int argc, char const *argv[])
{
	int n;
	scanf ("%d",&n);
	for (int i=1; i<=n; i++) {scanf ("%d",&a[i].val); a[i].id=i;}
	sort(a+1,a+1+n);
	int head=1,tail=n;
	while (tail>=head){
		vis[a[tail].id]=1;
		int s=a[tail-1].val;
		while (s<a[tail].val) s+=a[head++].val;
		tail-=2; 
	}
	for (int i=1; i<=n; i++)
		if (!vis[i]) printf("0");
		else printf("1");
	printf("\n");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43906000/article/details/107800144