您的位置:首页 > 其它

【JZOJ 3432】【OnlineJudge 1061】小M的服务器(含斜率优化解释)

2016-06-12 19:48 246 查看

Description

我们需要将一个文件复制到n个服务器上,这些服务器的编号为S1, S2, …, Sn。

首先,我们可以选择一些服务器,直接把文件复制到它们中;将文件复制到服务器Si上,需要花费ci > 0的置放费用。对于没有直接被复制文件的服务器Si来说,它依次向后检查Si+1, Si+2, …直到找到一台服务器Sj:Sj中的文件是通过直接复制得到的,于是Si从Sj处间接复制得到该文件,这种复制方式的读取费用是j – i(注意j>i)。另外,Sn中的文件必须是通过直接复制得到的,因为它不可能间接的通过别的服务器进行复制。我们设计一种复制方案,即对每一台服务器确定它是通过直接还是间接的方式进行复制(Sn只能通过直接方式),最终使每一台服务器都得到文件,且总花费最小。

Solution

首先这题的60分方法很简单,只用fi表示第i个必选的最小代价;

我们来考虑考虑用斜率优化,

设当前到i,状态j比k要优(j在前),则有:

fj+(j−i)∗(j−i−1)2<fk+(k−i)∗(k−i−1)2

移项:

fj−fk+j2−k2−j+k2j−k<i

用g(j,k)来表示这个东西,搞一波斜率优化DP即可,

复杂度:O(2n);

这里顺便讲一下斜率优化:

斜率优化

斜率优化的g函数是一定满足一个单调性的,前面的一定优于后面的,以本题为例:

设队列中的元素依次为j1,j2,,j3,...,

有:(这个显然)

i>g(j1,j2),i>g(j2,j3),i>g(j3,j4)...

也有:

i>g(j1,j2)>g(j2,j3)>g(j3,j4)>...

解释如下:假设相邻的3个元素:j1,j2,j3,

要想保证以上的式子,就必须当g(j1,j2)<g(j2,j3)时,删除j2,

因为:假设j2最优,则:

g(j1,j2)>i

g(j2,j3)<i

g(j2,j3)<i<g(j1,j2)

与上面的假设冲突,所以假设不成立,

所以当g(j1,j2)<g(j2,j3)时,删除j2,

所以整个式子满足:i>g(j1,j2)>g(j2,j3)>g(j3,j4)>...

Code

#include<cstdio>
#include<cstdlib>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(LL i=a;i>=b;i--)
using namespace std;
typedef long long LL;
const int N=1000500;
int read(int &n)
{
char ch=' ';int q=0,w=1;
for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar());
if(ch=='-')w=-1,ch=getchar();
for(;ch>='0' && ch<='9';ch=getchar())q=q*10+ch-48;n=q*w;return n;
}
int n;
int a
,S,T;
LL f
,d
;
double G(LL i,LL j){return(1.0*(f[i]-f[j]+(i*i-j*j-i+j)/2)/(i-j));}
int main()
{
read(n);
fo(i,1,n) read(a[i]);
f
=a
;d[S=T=1]=n;
fod(i,n-1,0)
{
while(T>S&&G(d[S],d[S+1])>i)S++;
f[i]=(d[S]-i)*(d[S]-i-1)/2+f[d[S]]+a[i];
while(T>S&&G(d[T-1],d[T])<G(d[T],i))T--;
d[++T]=i;
}
printf("%lld\n",f[0]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: