您的位置:首页 > 其它

hihocoder1269优化延迟

2016-03-08 11:21 239 查看
这道题其实只是一道很裸的二分+优先队列,然而本人比较笨,所以WA了好多次,下面附上代码

#include <iostream>
#include <queue>
#include <string.h>
using namespace std;
priority_queue<long long>que;
int n,t=99999999;
long long q;
int a[100005];
long long sum(int k)
{
int b[100005];
memset(b,0,sizeof(b));
long long sum2=0;
int i=1,j=1;
while(i<=n)
{
if(que.size()<k)
{
que.push(a[i]);
i++;
}
else
{
b[j++]=que.top();
que.pop();
que.push(a[i++]);
//每次弹出一个数值后,一定要再压入一个,否则的话,一个数会用到两个i,会溢出
}
}
while(!que.empty())
{
b[j++]=que.top();
que.pop();
}
for(int i=1; i<=n; i++)
sum2+=i*b[i];
//这里用数组会比较方便一点,当然你每弹出一个乘一次也是可以的,但是可能会比较麻烦一点
return sum2;
}

int main()
{
while(cin>>n>>q)
{
for(int i=1; i<=n; i++)
cin>>a[i];
int left=1;
int right=n;
//二分这块的处理很重要,很多人觉得简单,但是很容易写错

while(left<=right)//一定要有等号
{
int mid=(left+right)/2;
if(sum(mid)<=q)//一定要有等号
{
t=min(mid,t);
//之所以用二分是因为这道题随着k的增加,和逐渐减少,是递减的,但又不是严格意义上的递减有可能会出现相等的地方,所以这里要用一下min
right=mid-1;
}
else
{
left=mid+1;
}
}
if(sum(t)<=q)
cout<<t<<endl;
else cout<<-1<<endl;
//下面的这种也是可以的,但是我觉得并不是很好理解
/*while(left<=right)
{
int mid=(left+right)/2;
if(sum(mid)<=q)
{
right=mid-1;
}
else if(sum(mid)>q)
{
left=mid+1;
}
}
cout<<flag<<endl;
if(sum(left)<=q)
cout<<left<<endl;
else cout<<-1<<endl;*/

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: