C. Line Empire

题目:C. Line Empire

考点:思维

题意:给一个长度为 n n n 的数组 X X X 以及 a a a b b b,并且 0 < X 1 < X 2 < ⋅ ⋅ ⋅ < X n 0<X_1 < X_2 < ··· < X_n 0<X1<X2<<Xn ,求从 0 0 0 出发,到占领 X n X_n Xn 的最小花费。存在如下两个操作:

  • 将起点从 C 1 C_1 C1 转移到 C 2 C_2 C2 ,花费 a ∗ ∣ C 1 − C 2 ∣ a * |C_1 - C_2| aC1C2
  • 从起点 C 1 C_1 C1 出发占领 C 2 C_2 C2,花费 b ∗ ∣ C 1 − C 2 ∣ b*|C_1 - C_2| bC1C2

需要注意的是,当要被占领的 C 2 C_2 C2 与起点 C 1 C_1 C1 之间存在未被占领的点时, C 2 C_2 C2 将不能被占领。转而言之,需要依次占领 X 1 、 X 2 、 . . . 、 X n X_1、X_2、...、X_n X1X2...Xn

❌思路:通过题意能发现占领点的值一定会比出发点的值大,若要转移起点,则转移终点点一定会比起点大,即 C 2 > C 1 C_2 > C_1 C2>C1。面对一个新的待攻占点 C 3 C_3 C3,我们有两种选择,①直接从起点 C 1 C_1 C1 出发攻占待攻占点 C 3 C_3 C3,花费为 b ∗ ∣ C 1 − C 2 ∣ b * |C_1 - C_2| bC1C2,②先转移起点 C 1 C_1 C1 转移到 C 2 C_2 C2,再从新的起点 C 2 C_2 C2 出发到新的待攻占点 C 3 C_3 C3。两种情况取最小值。提取公式: a ∗ ( C 2 − C 1 ) + b ∗ ( C 3 − C 2 ) a * (C_2 - C_1) + b * (C_3 - C_2) a(C2C1)+b(C3C2) ,用二分找出合适的点 C 2 C_2 C2此思路完全错误,过不了样例,可用此思路推一下第二个例子,便可知道错误之处

✔思路:需要考虑的是从哪个点出发去攻占一个带攻占的点,转移起点会花费 a ∗ ∣ C 2 − C 1 ∣ a * |C_2 - C_1| aC2C1 ,需要判断这花费值不值,若后面还有 m m m 个带攻占点,此时存在关系 a ∗ ∣ C 2 − C 1 ∣ ≤ ∣ C 2 − C 1 ∣ ∗ m ∗ b a * |C_2 - C_1| \leq |C_2 - C_1| * m * b aC2C1C2C1mb ,则表明将起点转移到 C 2 C_2 C2 是值得的,这样就能 A C AC AC 了。

#include<stdio.h>

typedef long long ll;
const int N = 2e5 + 10;
ll s[N];
int n,a,b,k;

int main() {
	int t;
	scanf("%d",&t);
	while(t --) {
		
		scanf("%d %d %d",&n,&a,&b);
		for(int i=1;i<=n;i++) scanf("%lld",&s[i]);
		ll res = 0;
		int l = 0;
		for(int i=1;i<=n;i++) {
			res += b * (s[i] - s[l]);
			if((s[i] - s[l]) * a <= (s[i] - s[l]) * b * 1ll * (n - i)) {
				res += a * (s[i] - s[l]);
				l = i;
			}
		} 
		printf("%lld\n",res);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值