题解:
我们可以想到有两种清除的方式,一种是清楚的区间长度大于k的时候我们有两种方案,一种是先把区间缩小到k的倍数(这样无论区间里的值会不会大于端点两端的值都会被清楚),其次我们可以选择一个个的清除,这样的话必须满足区间内的最大值要小于我们左右端点中的一个。解题的时候避免右半边扫描不完全所以a,b数组可以都加一个哨兵0,这样的话在最后一个位置就一定能够扫描完。
#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef long long ll;
typedef long double ld;
const int N=2e5+10;
const int inf=1e18;
int a[N],b[N];
signed main()
{
int n,m; scanf("%lld%lld",&n,&m);
int x,k,y; scanf("%lld%lld%lld",&x,&k,&y);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
for(int i=1;i<=m;i++) scanf("%lld",&b[i]);
a[n+1]=b[n+1]=0;
int now=1,flag=0,ans=0;
// while(a[now]!=b[1]) now++;
for(int i=1;i<=m+1;i++){
int len=0,maxn=-1;
while(now<=n&&a[now]!=b[i]){
maxn=max(maxn,a[now]);
now++,len++;
}
// cout<<now<<endl;
if(now==n+2) {
flag=1;
break;
}
now++;
int res=inf;
for(int j=1;j*k<=len;j++){
res=min(res,j*x+(len-j*k)*y);
}
if(maxn<b[i]||(maxn<b[i-1]&&i-1>0)) res=min(res,len*y);
if(res==inf){
flag=1;
break;
}
ans+=res;
}
if(flag) puts("-1");
else printf("%lld\n",ans);
}