1000测试数据;
给定 n 快糖果,每个糖果的价值是 , 有 q 次询问,每次询问给定义一个 ,问至少吃多少块糖果可以是总价值大于等于 。
贪心的想,每次从最大的开始吃.
观察到 n,q<=1.5*1e5;
排序后,考虑用前缀和维护数组,对于每次询问,二分找即可。复杂度
核心代码超时了,为O(N) 于是考虑改为O(logN),前缀和加二分查询;
sort(g,g+n);
reverse(g,g+n);
while(m--)
{
int x;
cin>>x;
int sum=0;
int cnt=0;
while(sum<x)
{
sum+=g[cnt++];
}
if(x>sum2)
{
cnt=-1;
}
cout<<cnt<<endl;
}
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long LL;
const int N=150010;
int n,m;
int f[N];
int t;
int g[N];
int main()
{
cin>>t;
while(t--)
{
cin>>n>>m;
memset(g,0,sizeof g);
int sum2=0;
for(int i=0;i<n;i++)
{
cin>>g[i];
sum2+=g[i];
}
sort(g,g+n);
reverse(g,g+n);
for(int i=0;i<n;i++)//超时了,转化为前缀和,为O(1);二分查询为O(logn)
g[i+1]+=g[i];
while(m--)
{
int sum=0,x;
cin>>x;
int ans=lower_bound(g,g+n,x)-g;
if(ans==n)
cout<<-1<<endl;
else
cout<<ans+1<<endl;//下标从零开始,所有加1;
}
}
return 0;
}