购物(sum)

购物(sum)

题目描述

visit_world 有一个商店,商店里卖N商品,第ii 的价格为 a[[i]

我们称一个正整数K 是美妙的,当且仅当我们可以在商店里选购若干个商品,使得价格之和落在区间 [K,2K]中。

问:有多少个美妙的数。

输入

第一行一个整数NN。

接下来一行 NN个整数,描述数组a[]a[]。

输出

输出一行一个整数,表示答案。

样例输入

3
1 2 3

样例输出

6

提示

解释

可以证明1≤K≤6都是美妙的,除此之外的数都不是美妙的。

样例 2

/upload/file/20181017/20181017190720_44742.zip

数据范围和子任务

子任务 1(30 分):N≤100,ai≤100.

子任务 2(20 分):N≤100000,ai≤20.

子任务 3(20 分):N≤3,ai≤109.

子任务 4(30 分):N≤105,ai≤109

来源

hnsdfz国庆集训day2


solution

把a[i]从小到大排序

假设我已经知道了1~a[i-1]的答案为[1,sum(a[i])] (中间有的可能取不到)

对于单独的a[i] 答案是[ai+1/2,a[i]]

我们分个类:

1 a[i]>sum 

如果a[i]+1/2>sum[i] 那么sum~a[i]+1/2 一定取不到(a[i]之后都大于a[i])

反之一定可以,也就是把右端改成a[i]+sum;

2.a[i]<sum 直接把a[i]叠上sum就好的,也是把右端改成a[i]+sum;

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
int n,a[500005];
ll sum,ans;
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++){scanf("%d",&a[i]);sum+=a[i];}
    sort(a+1,a+n+1);
    ll la=1;
    for(int i=1;i<=n;i++){
        ll l=(a[i]+1)/2;
        if(l>la)ans=ans+l-la;
        la=la+a[i];
    }
    cout<<sum-ans<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/liankewei/p/10358820.html