CF1380D.Berserk And Fireball(思维)
/* *CF1380D.Berserk And Fireball *n个战士站成一排,分别有武力值ai。 *你有两种法术:火球和激怒。 *火球可以消耗x个法力,消灭连续k个战士。 *激怒可以消耗y个法力,选择相邻的两个战士,武力值大的会消灭武力值小的 *求最后留下的战士和数组b一样所需要的最小法力花费 *题解: *划分为多个区间 *如果当前区间的长度len<k *区间最大值大于左右端点,则无解,因为无法消去最大值 *区间最大值小于左右端点,消费就是len*y *如果当前区间的长度len>=k *区间最大值大于左右端点,那必须花费一个x来把最大值消掉。 */ #include<bits/stdc++.h> using namespace std; const int maxn=2e5+100; typedef long long ll; int a[maxn]; int b[maxn]; ll n,m,x,k,y; int main () { scanf("%lld%lld%lld%lld%lld",&n,&m,&x,&k,&y); for (int i=1;i<=n;i++) scanf("%d",&a[i]); for (int i=1;i<=m;i++) scanf("%d",&b[i]); a[n+1]=b[m+1]=-1; ll ans=0; for (int i=1,j=0;i<=m+1;i++) { int l=j+1,r=j+1,len=0,Max=-1; while (r<=n+1&&a[r]!=b[i]) Max=max(Max,a[r]),r++; if (r>n+1) { ans=-1;break; } len=r-l; if (len<k) { if (Max>max(a[l-1],a[r])) { ans=-1;break; } else { ans+=y*len; } } else { if (Max>max(a[l-1],a[r])) { ans+=x; len-=k; if (x<k*y) ans+=(len/k)*x+(len%k)*y; else ans+=y*len; } else { if (x<k*y) ans+=(len/k)*x+(len%k)*y; else ans+=y*len; } } if (a[r]!=b[i]) j=r+1; else j=r; } printf("%lld\n",ans); }