CF311B Cats Transport(斜率优化)

题目描述

Zxr960115 是一个大农场主。他养了m只可爱的猫子,雇佣了p个铲屎官。这里有一条又直又长的道路穿过了农场,有n个山丘坐落在道路周围,编号自左往右从1到n。山丘i与山丘i-1的距离是Di米。铲屎官们住在1号山丘。

一天,猫子们外出玩耍。猫子i去山丘Hi游玩,在Ti时间结束他的游玩,然后在山丘Hi傻等铲屎官。铲屎官们必须把所有的猫子带上。每个铲屎官直接从H1走到Hn,中间不停下,可以认为不花费时间的把游玩结束的猫子带上。每个铲屎官的速度为一米每单位时间,并且足够强壮来带上任意数量的猫子。

举个栗子,假装我们有两个山丘(D2=1),有一只猫子,他想去山丘2玩到时间3。然后嘞铲屎官如果在时间2或者时间3从1号山丘出发,他就能抱走猫子。如果他在时间1出发那么就不行(猫子还在玩耍)。如果铲屎官在时间2出发,猫子就不用等他(ΔT=0)。如果他在时间3出发,猫子就要等他1个单位时间。

你的任务是安排每个铲屎官出发的时间,最小化猫子们等待的时间之和。

题解

一个裸的斜率优化……我竟然没有看出来……

每一只猫等待的时间是铲屎官出发的时间-到原点的路程+猫出现的时间

那么我们对每一只猫记录一下-到原点的路程+猫出现的时间,然后sort一下,那么就是把这个序列分成p个区间,每个区间权值为最大的数与每一个数的差之和,然后求最小权值

那么直接上斜率优化

 1 //minamoto
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #define ll long long
 6 using namespace std;
 7 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
 8 char buf[1<<21],*p1=buf,*p2=buf;
 9 inline int read(){
10     #define num ch-'0'
11     char ch;bool flag=0;int res;
12     while(!isdigit(ch=getc()))
13     (ch=='-')&&(flag=true);
14     for(res=num;isdigit(ch=getc());res=res*10+num);
15     (flag)&&(res=-res);
16     #undef num
17     return res;
18 }
19 const int N=100005;
20 int q[N],h,t,n,m,p,r;ll dp[2][N],c[N],d[N],sum[N];
21 inline double slope(int j,int k){return (dp[r^1][j]+sum[j]-dp[r^1][k]-sum[k])*1.0/(j-k);}
22 int main(){
23     //freopen("testdata.in","r",stdin);
24     n=read(),m=read(),p=read();
25     for(int i=2;i<=n;++i) d[i]=read()+d[i-1];
26     for(int i=1;i<=m;++i){
27         int h=read(),t=read();
28         c[i]=t-d[h];
29     }
30     sort(c+1,c+1+m);
31     for(int i=1;i<=m;++i) sum[i]=sum[i-1]+c[i];
32     for(int i=1;i<=m;++i) dp[1][i]=c[i]*(i-1)-sum[i-1];
33     for(int i=2;i<=p;++i){
34         r=i&1;
35         h=t=0;
36         for(int i=1;i<=m;++i){
37             while(h<t&&slope(q[h],q[h+1])<c[i]) ++h;
38             dp[r][i]=dp[r^1][q[h]]+c[i]*(i-q[h])-sum[i]+sum[q[h]];
39             while(h<t&&slope(q[t],q[t-1])>slope(q[t],i)) --t;q[++t]=i;
40         }
41     }
42     printf("%lld
",dp[p&1][m]);
43     return 0;
44 }
原文地址:https://www.cnblogs.com/bztMinamoto/p/9553531.html