Educational Codeforces Round 91 D. Berserk And Fireball

题目描述

There are n warriors in a row. The power of the i-th warrior is ai. All powers are pairwise distinct.
You have two types of spells which you may cast:
Fireball: you spend x mana and destroy exactly k consecutive warriors;
Berserk: you spend y mana, choose two consecutive warriors and the warrior with greater power destroys another chosen warrior.
For example, let the powers of warriors be [2,3,7,8,11,5,4], and k=3. If you cast Berserk on warriors with powers 8 and 11, the resulting sequence of powers becomes [2,3,7,11,5,4]. Then, for example, if you cast Fireball on consecutive warriors with powers [7,11,5], the resulting sequence of powers becomes [2,3,4].
You want to turn the current sequence of warriors powers a1,a2,…,an into b1,b2,…,bm. Calculate the minimum amount of mana you need to spend on it.

Input

The first line contains two integers n and m (1≤n,m≤2⋅105) — the length of sequence a and the length of sequence b respectively.
The second line contains three integers x,k,y (1≤x,y,≤109;1≤k≤n) — the cost of fireball, the range of fireball and the cost of berserk respectively.
The third line contains n integers a1,a2,…,an (1≤ai≤n). It is guaranteed that all integers ai are pairwise distinct.
The fourth line contains m integers b1,b2,…,bm (1≤bi≤n). It is guaranteed that all integers bi are pairwise distinct.

Output

Print the minimum amount of mana for turning the sequnce a1,a2,…,an into b1,b2,…,bm, or −1 if it is impossible.

Examples

input
5 2
5 2 3
3 1 4 5 2
3 5
output
8
input
4 4
5 1 4
4 3 1 2
2 4 3 1
output
-1
input
4 4
2 1 11
1 3 2 4
1 3 2 4
output
0

题目大意

n个战士排成一排,分别有个武力值a[i]。你有两种法术,一个是火球(花费x个法力,消灭连续k个战士),一个是激怒(花费y个法力,选择相邻两个战士,武力值大的会消灭武力值小的)。求最后留下的战士排列成b[i]需要的最小法力花费

题目分析

我们只需要将a[]中元素和b[]中元素进行一一比较,找出a[]中那些区间要被删除即可。如果a[]只通过删除某些数不能变成b[]或者a[]中某个应该被删除的区间无法通过上述两种法术完全删除,那么输出-1。

利用两种法术删除某个区间中的所有数,且得到最小法力花费的方法:
设该区间为[l,r],首先看看与该区间相邻的两个数a[l-1],a[r+1]是否有一个大于区间内的最大值(判断能否只通过法术(2)来消除区间内的所有数)。
如果区间的长度len
然后就是找出最小的法力花费了:
我们必须使用法术(2)来消除至少len%k个数(因为法术(1)每次都只能消除连续的k个数)。剩下的len-k个数我们就要通过判断来确定使用那种方法了(注:后面的len都是len-=k后的)。
如果用法术(2)删除k个数需要的法力大于等于x(y*k>=x),那么剩下的数就可以只用法术(1)来删除了。
如果y*k
如果y*k

代码如下
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define LL long long
#define PII pair
using namespace std;
const int N=2e5+5;
LL n,m,x,y,k;		//k*y有可能爆int,所以最后用long long
int a[N],b[N];
bool remove(int l,int r,LL &ans)
{
	if(l>r) return true;
	bool st=false;				//判断条件1
	int max=*max_element(a+l,a+1+r);
	if(l-1>=0&&a[l-1]>max) st=true;
	if(r+1<n&&a[r+1]>max) st=true;
	
	int len=r-l+1;
	if(len<k&&!st) return false;
	
	int t=len%k;		//法术(2)删除len%k个数
	ans+=t*y;
	len-=t;
	
	if(k*y>=x) ans+=len/k*x;
	else if(st) ans+=len*y;
	else ans+=(len-k)*y+x;
	
	return true; 
}
int main()
{
	scanf("%d %d",&n,&m);
	scanf("%d %d %d",&x,&k,&y);
	
	for(int i=0;i<n;i++)
		scanf("%d",&a[i]);
	for(int i=0;i<m;i++)
		scanf("%d",&b[i]);
	
	int posa=0,posb=0,s=-1;
	LL ans=0;		//记录答案
	while(posb<m)
	{	
		while(posa<n&&a[posa]!=b[posb]) posa++;		//将a[]和b[]进行一一比对
		
		if(posa==n) {puts("-1"); return 0;}			//a[]只通过删除一些元素无法与b[]相等
		
		if(!remove(s+1,posa-1,ans)) {puts("-1"); return 0;}	//判断能否把一个区间的数完全删除
		
		s=posa;
		posb++;
	}
	if(!remove(s+1,n-1,ans)) {puts("-1"); return 0;}
	
	printf("%lld\n",ans); 
	return 0;
}

你可能感兴趣的:(Codeforces)