题目链接:https://codeforces.com/gym/102392/problem/E
题意:给定n个人年龄,年龄达到lc才能骑车,骑车可以载k-1人,骑车代价为pc;年龄达到lm才能骑motor,motor不能载人;可以用魔法,将一个人年龄转移到另一个人,转移一岁的代价为t,但不能转移超过d岁,及a岁的人,其年龄变化范围为
.
题解:枚举骑摩托数,将年龄排序,双指针来弄。代码实现具体细节比较多。
代码copy自vj
//coded by ZJUT_7
#include<bits/stdc++.h>
using namespace std;
const int maxn=100010;
#define inf 0x3f3f3f3f3f3f3f3f
#define ll long long
ll a[maxn];
int main(){
ll n,k,lc,lm,pc,pm,t,d;
scanf("%I64d%I64d%I64d%I64d%I64d%I64d",&n,&k,&lc,&pc,&lm,&pm);
scanf("%I64d%I64d",&t,&d);
for(int i=1;i<=n;i++) scanf("%I64d",&a[i]);
sort(a+1,a+n+1);
ll need=0,have=0,cost=0;
ll ans=inf;
int illegal=0;
for(int i=1;i<=n;i++){
have+=max(0LL,min(d,a[i]-lm));
need+=max(0LL,min(d,lm-a[i]));
if(a[i]+d<lm) illegal++;
}
cost=pm*n+need*t;
if(illegal==0&&have>=need) ans=cost;
int s=1,e=n;
ll cnt=0;
while(e-s+1>=k){
cnt++;
for(int i=0;i<k-1;i++){
need-=max(0LL,min(d,lm-a[i+s]));
have+=min(d,min(lm,a[i+s])-1);
if(a[i+s]+d<lm) illegal--;
}
need+=max(0LL,lc-max(lm,a[e]));
have-=max(0LL,min(d,a[e]-lm));
have+=max(0LL,min(d,a[e]-lc));
if(a[e]+d<lc) break;
cost=pm*(n-cnt*k)+cnt*pc+need*t;
if(illegal==0&&have>=need) ans=min(ans,cost);
s+=k-1;
e--;
}
if(a[e]+d>=lc){
cnt++;
for(int i=0;i<e-s;i++){
need-=max(0LL,min(d,lm-a[i+s]));
have+=min(d,min(lm,a[i+s])-1);
if(a[i+s]+d<lm) illegal--;
}
need+=max(0LL,lc-max(lm,a[e]));
have-=max(0LL,min(d,a[e]-lm));
have+=max(0LL,min(d,a[e]-lc));
cost=cnt*pc+need*t;
if(illegal==0&&have>=need) ans=min(ans,cost);
}
if(ans!=inf)
printf("%I64d\n",ans);
else
puts("-1");
}