萌新斜率优化求调

P2365 任务安排

@[kirihara233](/user/701221) 没有加入新的点
by Hayzeros @ 2022-11-24 14:16:41


@[kirihara233](/user/701221) 少了句```q[++r]=i```
by yinhee @ 2022-11-24 14:28:07


@[kirihara233](/user/701221) 帮您调过了。 几点问题(很多地方我是为了方便调试改的,改回去也应该没什么问题): - 计算斜率时最好强制类型转换成 `long double` 防止精度损失~~消失~~,或进行一个移项。 - 不要忘记加点。 - 刚开始要默认加入一个点 $0$,否则第一个任务总是会被分出去的。 - 弹出尾部时的条件有问题。 - 最好写 `l<r` 而不是 `l<=r`,当 `l==r` 时可能会有问题出现 [~~综上所述,我要给我的学习笔记引个流!~~](https://www.cnblogs.com/Keven-He/p/16027921.html) ```cpp /* 本提交仅用于帮助@[kirihara233](/user/701221)调试代码 */ #include<stdio.h> #define N 5009 #define int long long inline int read() { register int ret = 0, f = 1; register char ch = getchar(); while (ch < '0' || ch > '9') (ch == '-') ? f = -1 : 0, ch = getchar(); while (ch >= '0' && ch <= '9') ret = (ret << 1) + (ret << 3) + (ch ^ 48), ch = getchar(); return ret * f; } int dp[N], t[N], f[N], q[N]; inline int min(int a, int b) {return a < b ? a : b;} #define slope(j, k) (long double)((long double)((long double)(dp[k]) - (long double)(dp[j])) / (long double)((long double)(f[k]) - (long double)(f[j]))) signed main() { register int n = read(), s = read(), i, j, l = 1, r = 1; for (i = 1;i <= n;++ i) t[i] = read() + t[i - 1], f[i] = read() + f[i - 1]; for (i = 1;i <= n;++ i) { while (l < r && slope(q[l], q[l + 1]) <= (long double)(t[i] + s)) ++ l; dp[i] = dp[q[l]] - (t[i] + s) * f[q[l]] + t[i] * f[i] + s * f[n]; while (l < r && slope(q[r - 1], q[r]) >= slope(q[r], i)) -- r; q[++ r] = i; // for (j = 0;j < i;++ j) // dp[i] = min(dp[i], dp[j] + t[i] * (f[i] - f[j]) + s * (f[n] - f[j])); } printf("%lld", dp[n]); return 0; } ```
by K8He @ 2022-11-24 14:36:52


@[Hayzeros](/user/130819) @[yinhee](/user/578590) @[Keven_He](/user/306045) 谢谢!
by char_cha_ch @ 2022-11-24 18:37:27


|