CF734C Anton and Making Potions 题解

题目大意

你需要做至少 \(n\) 瓶药水,每瓶药水需要用 \(x\) 秒制成。你还有两种法术,第一种法术共有 \(m\) 个,第 \(i\) 个需要用 \(b_i\) 点法力值,可以让每瓶药水的制作时长改为 \(a_i\) 秒;第二种法术共有 \(k\) 个,第 \(i\) 个需要用 \(d_i\) 点法力值,可以瞬间制作 \(c_i\) 瓶药水,且 \(c_i\) 和 \(d_i\) 非递减。但是每种法术只能用一个。你总共有 \(s\) 点法力值,求制作至少 \(n\) 瓶药水最少需要几秒。

算法分析

首先考虑不用法术和只用一种法术的情况,显然这里很好处理,直接枚举就行了。

然后考虑两种法术一起用的情况。注意到 \(c_i\) 和 \(d_i\) 非递减,也就是 \(c_i\) 和 \(d_i\) 有单调性,极易让人想到二分。所以我们先枚举第一种法术使用哪个,然后二分找到剩下的法力值所能使用的最优的第二种法术,这里的最优显然是最靠后的也就是 \(d_i\) 最大的。

#include<bits/stdc++.h>
#define int long long//记得开long long
using namespace std;
const int N=2e5+5;
int a[N],b[N],c[N],d[N];
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    int n,m,k,x,s;
    cin>>n>>m>>k>>x>>s;
    for(int i=1;i<=m;i++)cin>>a[i];
    for(int i=1;i<=m;i++)cin>>b[i];
    for(int i=1;i<=k;i++)cin>>c[i];
    for(int i=1;i<=k;i++)cin>>d[i];
    int ans=n*x;//不用法术
    for(int i=1;i<=m;i++){//只用一种法术
        if(b[i]>s)continue;
        ans=min(ans,a[i]*n);
    }
    for(int i=1;i<=k;i++){
        if(d[i]>s)continue;
        ans=min(ans,x*max(0ll,n-c[i]));//这里要特判一下,因为题目只要求至少做n瓶,而不是刚好,所以多做几瓶没有问题
    }
    for(int i=1;i<=m;i++){
        if(b[i]>=s)continue;
        int st=upper_bound(d+1,d+1+k,s-b[i])-d-1;
        //找到能使用的第二种法术中最优的一个
        if(!st)continue;
        ans=min(ans,a[i]*max(0ll,n-c[st]));
    }
    cout<<ans;
    return 0;
}
posted @ 2026-10-17 18:55  SCX2014  阅读(2)  评论(0)    收藏  举报