标签:pre 任务 std read getc bre while 题目 strong
机器上有N个需要处理的任务,它们构成了一个序列。这些任务被标号为1到N,因此序列的排列为1,2,3...N。这N个任务被分成若干批,每批包含相邻的若干任务。从时刻0开始,这些任务被分批加工,第i个任务单独完成所需的时间是Ti。在每批任务开始前,机器需要启动时间S,而完成这批任务所需的时间是各个任务需要时间的总和。注意,同一批任务将在同一时刻完成。每个任务的费用是它的完成时刻乘以一个费用系数Fi。请确定一个分组方案,使得总费用最小。
f[i]表示前i个物品进行分组的最小花费。
下面的\(c_i\)表示题目描述中\(c_i\)的前缀和,\(t_i\)表示题目描述中\(t_i\)的前缀和。
考虑\(n^2\)做法
由于每次分组都会导致后面的时刻后移,所以花费系数就是\(c_n-c_j\)。
\(f_i=min\{f_j+(c_n-c_j)(t_i-t_j+S)\},j\in[0,i)\)
\(n^2\)转移即可。
考虑优化成\(nlogn\)
将上面的式子展开并处理一下:
\(f_i=min\{f_j+c_nt_i-c_nt_j+c_nS-c_jt_i+c_jt_j-c_jS\}\\ =min\{t_i(c_n-c_j)+f_j-c_nt_j+c_nS+c_jt_j-c_jS\}\)
然后就很斜率优化了。。
可是\(t_i\)并没有单调性
所以不能直接单调队列优化。可以用一个单调栈维护凸包,然后查询的时候就在上面二分即可。
/*
* @Author: wxyww
* @Date: 2019-12-17 19:59:58
* @Last Modified time: 2019-12-17 21:13:05
*/
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<ctime>
using namespace std;
typedef long long ll;
const int N = 300100;
ll read() {
ll x = 0,f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1; c = getchar();
}
while(c >= '0' && c <= '9') {
x = x * 10 + c - '0'; c = getchar();
}
return x * f;
}
ll c[N],t[N],n;
ll S;
struct node {
ll k,b;
}q[N];
int top;
void ins(ll k,ll b) {
while(top >= 1) {
ll k2 = q[top].k,k3 = q[top - 1].k,b2 = q[top].b,b3 = q[top - 1].b;
if((b2 - b) * (k2 - k3) <= (b3 - b2) * (k - k2)) --top;
else break;
}
q[++top] = (node){k,b};
}
inline ll calc(ll k,ll b,ll x) {
return k * x + b;
}
ll get(ll x) {
int l = 1,r = top;
int ans = 0;
while(l <= r) {
int mid = (l + r) >> 1;
if(calc(q[mid].k,q[mid].b,x) > calc(q[mid - 1].k,q[mid - 1].b,x)) r = mid - 1;
else ans = mid,l = mid + 1;
}
return calc(q[ans].k,q[ans].b,x);
}
int main() {
n = read(),S = read();
for(int i = 1;i <= n;++i) {
t[i] = t[i - 1] + read();c[i] = c[i - 1] + read();
}
q[0].k = c[n],q[0].b = S * c[n];
ins(c[n],S * c[n]);
ll now = 0;
for(int i = 1;i <= n;++i) {
now = get(t[i]);
ins(c[n] - c[i],now + c[i] * t[i] - c[n] * t[i] + S * (c[n] - c[i]));
}
cout<<now;
return 0;
}
标签:pre 任务 std read getc bre while 题目 strong
原文地址:https://www.cnblogs.com/wxyww/p/bzoj2726.html