两种操作,一种将长度为
k
k
k 的序列消除(删
k
k
k 个数),一种除去指定的连续两个数字中小的那个(删一个数)。
首先简单判断一下
b
b
b 是不是
a
a
a 的子序列,顺便记录下所有要删除的部分。
然后对于长度小于
k
k
k 的部分,我们只能选择单删,问题就是要保证删除的这段区间的数字都小于区间两端的数字,否则删除失败。
对于长度大于等于
k
k
k 的部分,我们要考虑性价比。是单删
k
k
k 次赚,还是一次删
k
k
k 个赚。如果该部分存在比两端数字都大的数,就至少需要一次群删,也就是需要操作一次删
k
k
k 个。
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long LL;
const int maxn = 2e5 + 5;
int a[maxn], b[maxn];
queue<pair<int, int> > q;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n, m;
LL x, k, y, ans = 0;
bool flag = true;
cin >> n >> m;
cin >> x >> k >> y;
for(int i = 1; i <= n; i++)
cin >> a[i];
for(int i = 1; i <= m; i++)
cin >> b[i];
int now = 1, cnt = 1, l = 1, r;
while(now <= m && cnt <= n){
if(b[now] == a[cnt]){
now++;
if(l != cnt){
q.push(make_pair(l, cnt - 1));
}
l = cnt + 1;
}
cnt++;
}
if(l != 0 && l != n + 1)
q.push(make_pair(l, n));
else if(l == 0 && cnt != n + 1)
q.push(make_pair(cnt, n));
if(now > m){
if(k*y >= x){
while(!q.empty()){
l = q.front().first;
r = q.front().second;
q.pop();
if(r - l + 1 >= k)
ans += (r - l + 1)/k*x + ((r - l + 1)%k)*y;
else{
for(int i = l ; i <= r; i++)
if(a[i] > a[l - 1] && a[i] > a[r + 1]){
flag = false;
break;
}
if(flag)
ans += (r - l + 1)*y;
else
break;
}
}
if(flag)
cout << ans << endl;
else
cout << -1 << endl;
}else{
while(!q.empty()){
l = q.front().first;
r = q.front().second;
q.pop();
if(r - l + 1 >= k){
bool need = false;
for(int i = l ; i <= r; i++)
if(a[i] > a[l - 1] && a[i] > a[r + 1]){
need = true;
break;
}
if(need) ans += x + (r - l + 1 - k)*y;
else ans += (r - l + 1)*y;
}
else{
for(int i = l ; i <= r; i++)
if(a[i] > a[l - 1] && a[i] > a[r + 1]){
flag = false;
break;
}
if(flag)
ans += (r - l + 1)*y;
else
break;
}
}
if(flag)
cout << ans << endl;
else
cout << -1 << endl;
}
}else
cout << -1 << endl;
return 0;}