Loading

题解:AT_discovery_2016_final_b DDPC特別ビュッフェⅡ

题目大意

给你 \(n\) 碟菜,第 \(i\) 碟菜有 \(a_i\) 的价值,在 \(t_i\) 秒时,这碟菜会消失。

初始 \(0\) 秒,你可以用 \(1\) 秒的时间吃掉一碟菜,但如果这碟菜消失了,就不能吃。

也就是说,当前时间为 \(s\) 秒,若 \(s+1 \le t_i\),则你可以吃掉第 \(i\) 碟菜,\(s\) 变为 \(s+1\)

当吃掉的菜价值总和不小于 \(m\) 时,你就吃饱了。

求你最少几秒才能吃饱(可能不能吃饱,无解)。

解题思路

考虑贪心,每秒钟取当前价值最高的菜。

发现很容易 Hack。

比如:\(n=2,m=3,a={1,2},t={1,2}\)

这样就会先吃掉第 \(2\) 盘菜,然后第 \(1\) 盘菜就消失了,贪心策略失败。

发现其实可以反悔贪心,优先吃快消失的菜。

当前菜已消失时,就可以将过去吃过价值最低的菜替换为当前菜,即反悔。

最后把吃掉的多余的菜去掉,剩下菜的数量即为答案。

代码

#include<map>
#include<set>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<string>
#include<bitset>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN=1e5+10;
const int N=1e5;
const int INF=0x3f3f3f3f;
const long long LINF=0x3f3f3f3f3f3f3f3f;
int n,m;
struct node{
    int t,val;//菜的消失时间和价值
}a[MAXN];
bool cmp(node x,node y){
    return ((x.t<y.t)|(x.t==y.t&&x.val>y.val));
}
priority_queue < int,vector<int>,greater<int> > q;
signed main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i].t);
    }
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i].val);
    }
    sort(a+1,a+1+n,cmp);//贪心,先按消失时间排序
    int tim=0;//当前时间
    long long sum=0;//价值总和
    for(int i=1;i<=n;i++)
    {
        if(tim+1<=a[i].t){//够吃得下当前菜
            sum+=a[i].val;
            q.push(a[i].val);
            tim++;
        }
        else if((!q.empty())&&(q.top()<a[i].val)){//不够吃下当前菜,返回
            sum-=q.top();
            sum+=a[i].val;
            q.pop();
            q.push(a[i].val);
        }
    }
    if(sum<m){
        puts("-1");
        return 0;
    }
    while(sum-q.top()>=m)//把吃掉的多余的菜去掉
    {
        tim--;
        sum-=q.top();
        q.pop();
    }
    printf("%d\n",tim);
    return 0;
}
posted @ 2025-02-09 07:01  Mathew_Miao  阅读(7)  评论(0)    收藏  举报