一共需要做N个物品,其中有类型1的魔法m个,类型2的魔法K个。
如果不使用魔法的情况下,做一个物品需要X的时间。
此时魔法值为S,使用魔法需要消耗对应的魔法值。
类型1的魔法作用为:将物品制作时间减少至ai.需要消耗的魔法值为bi.
类型2的魔法作用为:一瞬间制作出ci个物品,同时消耗魔法值为ci.
要求每种魔法最多只能使用一个。
对应求制作N个物品的最小时间花费。
思路:
1、首先我们可以预处理出:
①不使用任何魔法的时间花费
②只使用类型1的魔法的时间花费
③只使用类型2的魔法的时间花费
然后维护上述三种情况的最小值。
2、那么接下来处理两种魔法各使用一个的情况:
①观察到ci和di都是非递减的,那么我们考虑先枚举类型1的魔法使用哪一个。
②那么肯定这样一个问题:此时这样的情况下,我们肯定是消耗魔法越高越好,因为di是非递减的同时,ci也是非递减的。
③那么我们二分查找剩余的魔法值能够使用的魔法中,最高制作ci的数目。
④那么此时情况的时间花费就已知了,过程维护最小即可。
Ac代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define ll __int64
ll n,m,k,x,s,output;
struct node
{
ll bi;
ll cost;
}one[200060];
struct node2
{
ll ci;
ll cost;
}two[200060];
int main()
{
while(~scanf("%I64d%I64d%I64d",&n,&m,&k))
{
scanf("%I64d%I64d",&x,&s);
output=n*x;
for(int i=0;i<m;i++)
{
scanf("%I64d",&one[i].bi);
}
for(int i=0;i<m;i++)
{
scanf("%I64d",&one[i].cost);
if(s>=one[i].cost)
{
output=min(output,one[i].bi*n);
}
}
for(int i=0;i<k;i++)
{
scanf("%I64d",&two[i].ci);
}
for(int i=0;i<k;i++)
{
scanf("%I64d",&two[i].cost);
if(s>=two[i].cost)
{
ll tmp=n-two[i].ci;
if(tmp<0)tmp=0;
output=min(output,tmp*x);
}
}
for(int i=0;i<m;i++)
{
int l=0;
int r=k-1;
ll ans=5000000000000000000;
while(r>=l)
{
int mid=(l+r)/2;
if(two[mid].cost+one[i].cost>s)
{
r=mid-1;
}
else
{
ll tmp=n-two[mid].ci;
if(tmp<0)tmp=0;
ans=min(ans,tmp*one[i].bi);
l=mid+1;
}
}
output=min(output,ans);
}
printf("%I64d\n",output);
}
}