笔记-[SDOI2012]任务安排

笔记-[SDOI2012]任务安排

[SDOI2012]任务安排


(f_i) 表示分配到第 (i) 个任务的最小费用。

(st_i=sum_{h=1}^iT_h)(sc_i=sum_{h=1}^iC_h)

[egin{split} f_i=&min{f_j+st_i(sc_i-sc_j)+s(sc_n-sc_j)}\ f_i=&f_j+st_isc_i-st_isc_j+scdot sc_n-scdot sc_j\ f_j-scdot sc_j=&st_isc_j+f_i-st_isc_i-scdot sc_n\ end{split} \ herefore egin{cases} y=f_j-scdot sc_j\ k=st_i\ x=sc_j\ b=f_i-st_isc_i-scdot sc_n\ end{cases} \ Large y=kx+b ]


Code

#include <bits/stdc++.h>
using namespace std;

//Start
#define re register
#define il inline
#define mk make_pair
#define pb push_back
#define db double
#define lng long long
#define fi first
#define se second
const int inf=0x3f3f3f3f;
const lng INF=0x3f3f3f3f3f3f3f3f;

//Data
int n,s;
vector<lng> st,sc,f;

//DP
int l,r;
vector<int> q;
il lng X(re int j){return sc[j];}
il lng Y(re int j){return f[j]-sc[j]*s;}
il int Find(re int L,re int R,re lng x){
	while(L<R){
		re int mid=(L+R)>>1;
		if(Y(q[mid+1])-Y(q[mid])>=x*(X(q[mid+1])-X(q[mid]))) R=mid;
		else L=mid+1;
	}
	return q[R];
}
il lng DP(){
	l=1,r=0,q=vector<int>(n+7),q[++r]=0,f=vector<lng>(n+7);
	for(re int i=1;i<=n;i++){
		re int j=Find(l,r,st[i]);
		f[i]=f[j]+st[i]*(sc[i]-sc[j])+(sc[n]-sc[j])*s;
		while(l<r&&(Y(q[r-1])-Y(q[r]))*(X(q[r])-X(i))
		>=(Y(q[r])-Y(i))*(X(q[r-1])-X(q[r]))) r--; q[++r]=i;
	}
	return f[n];
}

//Main
int main(){
	scanf("%d%d",&n,&s),st.pb(0),sc.pb(0);
	for(re int i=1,t,c;i<=n;i++) scanf("%d%d",&t,&c),st.pb(st[i-1]+t),sc.pb(sc[i-1]+c);
	printf("%lld
",DP());
	return 0;
}

[Hugecolor{#ddd}{ exttt{---END---}} ]

原文地址:https://www.cnblogs.com/George1123/p/12600676.html