3432. 【GDOI2014模拟】服务器

Description

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

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

Input

输入文件的第一行有一个整数n,表示服务器的数目。输入文件的第二行有n个整数,顺数第i个表示ci:在Si上直接复制文件的费用。

Output

输出文件中只包含一个整数,即最少需要花费的费用。

Sample Input

10

2 3 1 5 4 5 6 3 1 2

Sample Output

18

Data Constraint

60%的数据中,1 <= n <= 1 000

100%的数据中,1 <= n <= 1 000 000

80%的数据中, 1 <= ci <= 50

100%的数据中,1 <= ci <= 1 000 000 000

最终结果可能较大,请注意选择适当的数据类型进行计算。

Hint

这里写图片描述

题解(转载LYD729)
f[i]=min(f[j]+(ji)∗(ji1)2+a[i]),j>i 
这样做是O(n2)的,TLE。 
对于当前的ii是从后往前枚举的),设有两个决策j,k,j优于k,那么需要满足的条件是 
f[j]+(ji)∗(ji1)2+a[i]<f[k]+(k−i)∗(k−i1)2+a[i]
移项,整理得 
f[j]−f[k]+j2−k2−j+k2j−k<i
设g(j,k)表示不等式左边。 
所以我们维护一个单调递减的队列,里面大概长成这个样子 
i>g(jl,jl+1)>g(jl+1,jl+2)>⋯>g(jr−1,jr)
队头即jl为对于当前的i的最优解。 
然后我们i是递减的,所以一旦有i<g(jl,jl+1)则令jl出队,因为这说明jl不再是最优的了。 
而做完当前的i之后,也要将其加入队列。 
若有g(jr−1,jr)<g(jr,i)则说明jr永远不可能取到最优了,证明如下: 
采用反证法,假设jr能够取到最优,则 
jr优于jr−1等价于g(jr−1,jr)>i, 
jr优于i等价于g(jr,i)<i。 
综合上面两个不等式,得 
g(jr,i)<i<g(jr−1,jr)。 
惊奇地发现不等式出现了矛盾! 
得证! 
所以要把jr踢掉,一直做下去直到不满足上述条件,然后让i入队。 
但是,naive的我曾经有过这样一个疑问,为什么不能直接用g(i,jr)即i优于jr来判断队尾的出队情况呢? 
因为当前i优于jr并不代表以后的i亦优于jr(这个证明是感性的,凑合理解吧)。 
#include<cstdio>
#define N 1000005
#define ll long long
using namespace std;
int n;
ll a[N],f[N],q[N];
double g(ll j,ll k)
{
    return (f[j]-f[k]+(j*j-k*k-j+k)/2.0)/(j-k);
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%lld",&a[i]);    
    f[n]=a[n];
    int h=1,t=1;
    q[1]=n;
    for(int i=n-1;i>=0;i--)
    {
        while(h<t&&i<g(q[h],q[h+1])) h++;
        int j=q[h];
        f[i]=f[j]+a[i]+(j-i)*(j-i-1)/2;
        while(h<t&&g(q[t-1],q[t])<g(i,q[t])) t--;
        q[++t]=i;
    }
    printf("%lld",f[0]);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值