题目
问题描述
假设在
X
X
X轴上标记了
n
n
n个坐标为正整数的城池,而我们的都城在原点。
作为国王,需要征服所有的城池,国王有两种操作:
1.迁都,将都城
c
1
c_1
c1迁至已攻克的城池
c
2
c_2
c2,消耗为
a
∗
∣
c
1
−
c
2
∣
a*|c_1-c_2|
a∗∣c1−c2∣;
2.攻城,从都城
c
1
c_1
c1出发攻克城池
c
2
c_2
c2,消耗为
b
∗
∣
c
1
−
c
2
∣
b*|c_1-c_2|
b∗∣c1−c2∣,只能攻克与领土相邻的城池。
问国王征服所有城池的最小耗费为多少?
需要注意的是,迁都只能迁至某座城池;攻城不会改变都城的位置。
分析
有一个错误的贪心思路,每次都尽可能迁都,这样的解不一定是最优解。
当都城最终的位置确定时,我们可以用式子直接确定这一次的消耗量,可以由三部分来求出:
1.迁都耗费;
2.定都前攻城耗费;
3.定都后攻城耗费。
然后从中选出最小值即可。
代码
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
#define fir(i, a, b) for (ll i = (a); i <= (b); i++)
#define rif(i, a, b) for (ll i = (a); i >= (b); i--)
const int N=2e5+5;
ll t,n,a,b,tmp,sum[N],pos[N],cab[N];
int main(){
cin>>t;
while(t--){
ll ans=0;
memset(sum,0,sizeof sum);
cin>>n>>a>>b;
fir(i,1,n){
cin>>pos[i];
sum[i]+=sum[i-1]+pos[i];
}
ans=b*sum[n];
fir(i,1,n){
cab[i]=a*pos[i]+b*pos[i]+b*(sum[n]-sum[i]-(n-i)*pos[i]);
ans=min(ans,cab[i]);
}
cout<<ans<<endl;
}
return 0;
}