二分+堆——Codeforces812C Sagheer and Nubian Market

来源:互联网 发布:mysql结构化查询语言 编辑:程序博客网 时间:2024/05/17 05:05

题面:cf812c
简要题意:有n个纪念品,第i个纪念品底价为a[i],购买时如果购买k个,第i个纪念品的价格就是a[i]+k*i,问钱数为S时最多能买的纪念品个数以及购买这些纪念品所花费的最少钱数

直接二分要购买的纪念品个数即可
我的二分判断做法是开一个小根堆,然后依次把每个数当前的价格扔进去。。。
然后取出最小的mid个就可以了,如果符合答案那么这些取出的纪念品的价格总和就是最小花费数了
WA了四发不开心QAQ

#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<iostream>#include<cstdlib>#include<set>#include<map>#include<string>#include<ctime>#include<queue>#include<vector>using namespace std;typedef long long ll;priority_queue<ll,vector<ll>,greater<ll> >q;ll sum,n,m,ans1,ans2,a[100001];inline bool check(ll x){    sum=0;while(!q.empty())q.pop();    for(ll i=1;i<=n;i++)q.push(a[i]+x*i);    for(ll i=1;i<=x;i++)sum+=q.top(),q.pop();    return sum>m?0:1;}int main(){    scanf("%lld%lld",&n,&m);    for(ll i=1;i<=n;i++)scanf("%lld",&a[i]);    ll l=0,r=n;    while(l<=r){        ll mid=l+r>>1;        bool p=check(mid);        if(p)ans1=max(ans1,mid),ans2=max(ans2,sum),l=mid+1;        else r=mid-1;    }    printf("%lld %lld",ans1,ans2);}