[ SDOI2012] task scheduling
The slope Optimization Starter questions:
Set \ (f (x) \) of \ (F (x) \) of the post- conjugation and, \ (T (X) \) of \ (T (x) \) prefix and. \ (dp (i) \) indicating the completion of the first \ (i \) mandate minimum cost transfer:
\(dp(i)=\min \{dp(j) +f(j+1)\times(S+t(i)-t(j)) \}\)
Remove:
- And \ (j \) has nothing: no
- And only \ (j \) Related: \ (dp (J) + f (J + 1) \ Times (St (J)) \)
- And \ (i, j \) Related: \ (F (J +. 1) \ Times T (I) \)
We only found and (j \) \ can be directly related to the pre-treatment, the question now is to determine the \ (i \) How to quickly find a \ (j \)
Order \ (y_j = DP (J) + F (J +. 1) \ Times (St (J)) \) , \ (x_j = F (J +. 1) \) , the original formula can be written as:
\ [DP (I ) = y_j + x_jt (i) \]
Click conversion equation
\ [y_j = -t (i) x_j + dp (i) \]
The question now becomes identified a \ (i \) , to quickly find a previous \ (j \) so that \ (dp (i) \) Minimum
This thing as a straight line, it becomes I have a translation in the plane of the slope \ (- t (i) \ ) is a straight line, find a point now \ ((x_j, y_j) \ ) makes too at this point the slope is \ (- t (i) \ ) a straight line intercept as small as possible.
Blue: slope \ (- t (i) \ ) line
Purple Point: \ ((x_j, y_j) \)
Obviously, there can be seen in a \ (y \) is negative infinity axle has slowly move in a straight line (intercept gradually become larger), this line passes through the point in a sudden we set it At this intercept is the smallest of the intercept. Obviously, in this convex hull above a certain point, and the slope of the left and right sides of this point it must be left smaller, larger on the right (negative slope).
Dynamic Maintenance look like a convex hull.
//@winlere
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; typedef long long ll;
inline int qr(){
register int ret=0,f=0;
register char c=getchar();
while(c<48||c>57)f|=c==45,c=getchar();
while(c>=48&&c<=57) ret=ret*10+c-48,c=getchar();
return f?-ret:ret;
}
int n,s;
const int maxn=3e5+5;
int Ti[maxn],Fi[maxn];
ll st[maxn],sf[maxn];
ll x[maxn],y[maxn],q[maxn],dp[maxn];
int cnt;
inline ll getval(const int&i,const int&j){
return dp[j]+sf[j+1]*(s+st[i]-st[j]);
}
inline bool chek0(const int&i,const int&j,const ll&k){
return (long double)1.0*((y[i]+dp[i])-(y[j]+dp[j]))*(x[i]-x[k])<=(long double)1.0*((y[i]+dp[i])-(y[k]+dp[k]))*(x[i]-x[j]);
}
inline bool chek(const int&i,const int&j,const ll&k){
return (long double)1.0*(y[i]+dp[i])-(y[j]+dp[j])<=(long double)1.0*k*(x[i]-x[j]);
}
inline int lookup(const ll&k){
register int l=1,r=cnt-1,ret=cnt,mid;
while(l<=r){
mid=(l+r)>>1;
if(chek(q[mid],q[mid+1],k))
r=mid-1,ret=mid;
else l=mid+1;
}
return q[ret];
}
int main(){
n=qr();s=qr();
for(register int t=1;t<=n;++t)
Ti[t]=qr(),Fi[t]=qr(),st[t]=st[t-1]+Ti[t];
for(register int t=n;t>=0;--t) sf[t]=sf[t+1]+Fi[t];
for(register int t=0;t<=n;++t) y[t]=sf[t+1]*(s-st[t]),x[t]=sf[t+1];
q[cnt=1]=0;
for(register int t=1;t<=n;++t){
dp[t]=getval(t,lookup(-st[t]));
while(cnt>1&&chek0(q[cnt-1],q[cnt],t)) --cnt;
q[++cnt]=t;
}
cout<<dp[n]<<endl;
return 0;
}