这篇文章上次修改于 698 天前,可能其部分内容已经发生变化,如有疑问可询问作者。

题目传送门

题目意思:你有 $w$ 元,你只能从 $n$ 个商品选一个买买得起的,但是你可以用你有的商品换取 $n$ 个其他商品,换取的商品价值总和不能大于原来的。每个商品只有一个。

看了一眼数据范围:$1 \leq n\leq10^6$。
确定贪心。
首先买的商品价值越大越好,因为换取的商品的价值总和可以小于原来的商品。那就先贪心选择价值最大的可以选的商品。

商品在经过多次转换后不仅会使价值更分散(不能将多个商品合在一起兑换),也不会徒增商品价值,所以就一次到位。

怎么选才能最优,贪心啊。

从最小的开始选,再选第二小的,选不了了就输出答案。

记得边界条件。

//g++  7.4.0

#include <iostream>
#include <algorithm>
#include <cstdio>
inline int read()
{
	int x=0;
	bool flag=1;
	char c=getchar();
	while(c<'0'||c>'9')
	{
		if(c=='-')
			flag=0;
		c=getchar();
	}
	while(c>='0'&&c<='9')
	{
		x=(x<<1)+(x<<3)+c-'0';
		c=getchar();
	}
	return (flag?x:~(x-1));
}
using namespace std;
int a[100005];
int main()
{
    int n=read();
    for(int i=1;i<=n;i++){
        a[i]=read();
    }
    int w;
    w=read();
    sort(a+1,a+n+1);
    if(n==0||a[1]>w){
        printf("0");
        return 0;
    }
    int temp=upper_bound(a+1,a+n+1,w)-a-1;//在选择的时候,已经进行排序,所以直接二分查找能买到的价值最高的商品。
    int more=a[temp];
    for(int i=1;i<temp;i++){
        more-=a[i];
        if(more<0){
            printf("%d",max(i-1,1));
            return 0;
        }
    }
    printf("%d",max(1,temp-1));
    return 0;
}