社区讨论

斜率优化,全0 求助

P5017[NOIP 2018 普及组] 摆渡车参与者 2已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@lo260dd6
此快照首次捕获于
2023/10/23 08:34
2 年前
此快照最后确认于
2023/11/03 08:50
2 年前
查看原帖
CPP
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define int long long

using namespace std;

const int N = 510;
const int M = 4e6 + 10;

inline int read(){
	register int x = 0, f = 1; register char ch = getchar();
	for(; ch > '9' || ch < '0'; ch = getchar()) if(ch == '-') f = -1;
	for(; ch >= '0' && ch <= '9'; ch = getchar()) x = (x << 1) + (x << 3) + (ch ^ '0');
	return x * f;
}

int n, m;
int T[M], f[M], S[M], C[M];
int q[N], hh = 1, tt = 0;
int mx;

double slope(int j1, int j2){
	return (double)(1.0 * (f[j2] + S[j2] - f[j1] - S[j1]) / ((C[j2] == C[j1]) ? 1e9 : C[j2] - C[j1]));
}

signed main(){
	n = read(), m = read();
	for(int i = 1; i <= n; ++ i){ int a = read(); C[a] ++; S[a] += a; mx = max(mx, a); }
	for(int i = 1; i < mx + m; ++ i) C[i] += C[i - 1], S[i] += S[i - 1];
	q[++ tt] = 0;
	for(int i = 0; i < mx + m; ++ i){
		while(hh < tt and 1.0 * slope(q[hh], q[hh + 1]) <= 1.0 * i) hh ++;
		f[i] = min(C[i] * i - S[i], f[q[hh]] + C[i] * i - C[q[hh]] * i - S[i] + S[q[hh]]);
		while(hh < tt and slope(q[tt - 1], q[tt]) >= slope(q[tt - 1], i)) tt --;
		q[++ tt] = i;
	}
	int ans = 2e9;
	for (int i = mx; i < mx + m; i ++ )
		ans = min(ans, f[i]);
	cout << ans << endl;
	return 0;
}

回复

1 条回复,欢迎继续交流。

正在加载回复...