购物(sum)
【from new_dtoj 3966:购物(sum)】
题目描述
visit_world有一个商店,商店里卖N个商品,第i 个的价格为我们称一个正整数K是美妙的,当且仅当我们可以在商店里选购若干个商品,使得价格之和落在区间[K,2K]中。
问:有多少个美妙的数。
输入
第一行一个整数N。
接下来一行N个整数,描述数组a。
输出
输出一行一个整数,表示答案。
样例输入
3
1 2 3
样例输出
6
提示
解释
可以证明1≤K≤6 都是美妙的,除此之外的数都不是美妙的。
数据范围和子任务
N≤,≤且为正整数
子任务 1(30 分):N≤100,≤100 .
子任务 2(20 分):N≤,≤20.
子任务 3(20 分):N≤3,≤ .
子任务 4(30 分):N≤,≤ .
题解
首先我们先将从小到大排序,对于每个,它的合法区间是[(+1)/2,]
设表示前i个数的和
因为最终答案的范围在(+1)/2到中,所以我们可以考虑在这个范围内,哪几块的k值也是不能选的,最后减去即可
假设已经处理前i-1次要减去的值,现在考虑第i次要减去什么,这里应该分成两类
- (+1)/2<=
因为 (+1)/2<=,所以在(+1)/2到已经处理完全了,而~都是可取的,可以发现到这一块也处理过了,所以在这里并不需要减去什么 - (+1)/2>
同上方类似,唯一不同的是可以发现~(+1)/2中的k值是去不到的,所以要把这一块数的个数减去
具体代码如下
#include <cstdio>
#include <algorithm>
using namespace std;
int n;long long a[100005],m,s,r;
int main(){
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%lld",&a[i]);
sort(a+1,a+n+1);
for (int i=1;i<=n;s+=a[i],i++)
if (((a[i]+1)/2)>s) m-=((a[i]+1)/2)-s-1;
return printf("%lld\n",m+s),0;
}