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<k(此時只能通過法術(2)來消除區間內的數),且上述條件不成立,那么不能完全刪除這個區間中的所有數,輸出-1。
然后就是找出最小的法力花費了:
我們必須使用法術(2)來消除至少len%k個數(因為法術(1)每次都只能消除連續的k個數)。剩下的len-k個數我們就要通過判斷來確定使用那種方法了(注:后面的len都是len-=k后的)。
如果用法術(2)刪除k個數需要的法力大于等于x(y*k>=x),那么剩下的數就可以只用法術(1)來刪除了。
如果y*k<x且條件1成立,那么就可以用用法術(2)來消除剩下的所有數。
如果y*k<x且條件1不成立,即不能用法術(2)來刪除所有數,那么就用法術(2)刪除(len-k)個元素,最后只留下k個元素用法術(1)來消除。
代碼如下
#include <iostream> #include <cstdio> #include <cmath> #include <string> #include <cstring> #include <stack> #include <map> #include <queue> #include <vector> #include <set> #include <algorithm> #include <iomanip> #define LL long long #define PII pair<int,int> 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; //判斷條件1int 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; }總結
以上是生活随笔為你收集整理的Educational Codeforces Round 91 D. Berserk And Fireball的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: “IT 变革” 云 = 美国道富银行砍掉
- 下一篇: 汽车IC TPS7A6633QDGNRQ