BZOJ3437 小P的牧场(斜率优化dp)

题目link:http://www.lydsy.com/JudgeOnline/problem.php?id=3437;

略略读一下题,发现这题是一道dp

有一些牧场:

1 2 3 4 5 6 7 8 9 10

其中编号大的可以管住编号小的.

a[i]表示建站费用 b[i]表示养殖奶牛数目

dp方程大概就出来了

f[i]=min(f[j]+cost(j+1,i)) (0<j<i);

可是有些问题需要O(1)计算cost(j+1,i);

怎么办呢?

于是我想了一个很不清真的计算方法

开了两个数组

形式化的讲:

sumb[i]=sumb[i-1]+b[i]

sum[i]=sum[i-1]+sumb[i-1]

有什么意义呢

sumb[i]表示b的前缀和

sum[i]表示如果1到i-1都要由i控制的运输费用;(不计建站费用)

第一个转移是显然的

第二个转移是因为可以将运输想象成两部分,先运到i-1,再运到i

然后就可以O(1)计算cost(j+1,i)了

cost(j+1,i)=sum[i]-sum[j]-sumb[j]*(i-j)

这个文字比较难解释,还是看图吧

矩形的长指i-k

矩形的宽指b[k]

(j<k<i)

则矩形的面积指该点对sum的贡献

很显然,现在cost=3号区域的面积

已知:总面积=sum[i]; 1号区域面积=sum[j]; 2号区域面积=sumb[j]*(i-j);

所以cost(j+1,i)=sum[i]-sum[j]-sumb[j]*(i-j);

/-----------------分割线-----------------/

现在f[i]=min(f[j]+sum[i]-sum[j]-sumb[j]*(i-j)+a[i])

f[i]=min(f[j]-sum[j]-sumb[j]*(i-j))+sum[i]+a[i];

开始斜率优化!

1.去掉min,确认是维护下凸包

2.f[i]=f[j]-sum[j]-sumb[j]*(i-j)+sum[i]+a[i];

3.化式子f[i]+i*sumb[j]=f[j]-sum[j]+sumb[j]*j+const(这一坨是跟j无关的常量)

4.对应     b  +k    x      =y

然后一切就简单了

但是这题有坑点,a,b数组要开long long,题中的数据范围是假的

我因为括号写错了位置,WA一上午,最后只改了一个字符就AC了!QAQ

AC代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1000010;
int n,h,t,q[N];
long long a[N],b[N],sum[N],sumb[N],f[N];
inline double X(const int &j){
    return sumb[j];
}
inline double Y(const int &j){
    return f[j]-sum[j]+sumb[j]*j;
}
inline double Rate(const int i,const int j){
    return (Y(i)-Y(j))/(X(i)-X(j));
}
int main(){
    scanf("%d",&n);
    for (int i=1; i<=n; i++) scanf("%lld",&a[i]);
    for (int i=1; i<=n; i++) scanf("%lld",&b[i]);
    for (int i=1; i<=n; i++){
        sumb[i]=sumb[i-1]+b[i];
        sum[i]=sum[i-1]+sumb[i-1];
    }
    for (int i=1; i<=n; i++){
        while (h<t&&Rate(q[h],q[h+1])<i) ++h;
        f[i]=f[q[h]]+sum[i]-sum[q[h]]-sumb[q[h]]*(i-q[h])+a[i];
           while(h<t&&Rate(q[t-1],q[t])>Rate(q[t],q[i])) t--;
        q[++t]=i;
    }
    printf("%lld",f[n]);
}

不知道读者明白这题了没有,不明白的话请联系Yuhuger

时间: 2024-11-06 11:15:02

BZOJ3437 小P的牧场(斜率优化dp)的相关文章

bzoj3437小P的牧场 斜率优化dp

3437: 小P的牧场 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1542  Solved: 849[Submit][Status][Discuss] Description 小P在MC里有n个牧场,自西向东呈一字形排列(自西向东用1…n编号),于是他就烦恼了:为了控制这n个牧场,他需要在某些牧场上面建立控制站,每个牧场上只能建立一个控制站,每个控制站控制的牧场是它所在的牧场一直到它西边第一个控制站的所有牧场(它西边第一个控制站所在的牧场不被

BZOJ 3437 小P的牧场 斜率优化DP

题目大意:有些按照一字排列的牧场,每一个牧场有一个费用和放牧数量.现在要在一些牧场上建造控制站,目的是控制所有的牧场,建立控制站的基础费用就是每个牧场的费用,然后每一个牧场需要付这个牧场的放养数量*它与右边相邻的控制站的距离.求最小的费用. 思路:直接弄有些不好弄,需要两个前缀和来进行差分. sum[i] = Σsrc[i] _sum[i] = Σsrc[i]*i 然后DP方程就是f[i] = f[j] + (sum[i] - sum[j]) * i - _sum[i] + _sum[j] 简单

【BZOJ3437】小P的牧场 斜率优化 动态规划

呃,老规矩,方程.转化神马的都在代码注释里面. 不会斜率优化的移步这篇:http://blog.csdn.net/vmurder/article/details/41648159 没事闲的想看点经验的来"前一篇"http://blog.csdn.net/vmurder/article/details/41682901 代码: #include <cstdio> #include <cstring> #include <iostream> #inclu

bzoj 3437: 小P的牧场 -- 斜率优化

3437: 小P的牧场 Time Limit: 10 Sec  Memory Limit: 128 MB Description 小P在MC里有n个牧场,自西向东呈一字形排列(自西向东用1…n编号),于是他就烦恼了:为了控制这n个牧场,他需要在某些牧场上面建立控制站,每个牧场上只能建立一个控制站,每个控制站控制的牧场是它所在的牧场一直到它西边第一个控制站的所有牧场(它西边第一个控制站所在的牧场不被控制)(如果它西边不存在控制站,那么它控制西边所有的牧场),每个牧场被控制都需要一定的花费(毕竟在控

bzoj3437小P的牧场

bzoj3437小P的牧场 题意: n个牧场,在每个牧场见控制站的花费为ai,在该处建控制站能控制从此处到左边第一个控制站(或边界)之间的牧场.一个牧场被控制的花费等于它到控制它的控制站之间的牧场数目(不包括自身,但包括控制站所在牧场)乘上该牧场的放养量.求最小费用. 题解: 推公式: f[i]=f[j]+sigma(k,j+1,i)((i-k)*b[k])+a[i] =f[j]+sigma(k,j+1,i)(i*b[k]-k*b[k])+a[i] =f[j]+sigma(k,j+1,i)(i*

bzoj-4518 4518: [Sdoi2016]征途(斜率优化dp)

题目链接: 4518: [Sdoi2016]征途 Description Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地.除第m天外,每一天晚上Pine都必须在休息站过夜.所以,一段路必须在同一天中走完. Pine希望每一天走的路长度尽可能相近,所以他希望每一天走的路的长度的方差尽可能小. 帮助Pine求出最小方差是多少. 设方差是v,可以证明,v×m^2是一个整数.为了避免精度误差,输出结果时输出v×m^2. In

斜率优化DP总结

前言: 也是好久没有写题解了,最近主要学习了单调栈单调队列以及斜率优化DP这几个知识点,对于较难的斜率优化DP,做个小小的总结吧. 正(che)文(dan): T1 hdu 3507 在一个风和日丽的早上,你打开了网页,点进了hdu,偶然间看到了这道题,不屑的以为这仅仅是一个很水的DP,2分钟给出DP方程式,很快的写完后发现n的范围居然是500000,这让已经推出来的 O(n2)复杂度的递推式情何以堪,所以就产生了一种高逼格的优化方式:斜率优化. 这道题的方程式是什么呢? dp[i]=min(d

【bzoj3675】[Apio2014]序列分割 斜率优化dp

原文地址:http://www.cnblogs.com/GXZlegend/p/6835179.html 题目描述 小H最近迷上了一个分隔序列的游戏.在这个游戏里,小H需要将一个长度为n的非负整数序列分割成k+1个非空的子序列.为了得到k+1个子序列,小H需要重复k次以下的步骤: 1.小H首先选择一个长度超过1的序列(一开始小H只有一个长度为n的序列--也就是一开始得到的整个序列): 2.选择一个位置,并通过这个位置将这个序列分割成连续的两个非空的新序列. 每次进行上述步骤之后,小H将会得到一定

bzoj4518[Sdoi2016]征途 斜率优化dp

4518: [Sdoi2016]征途 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1657  Solved: 915[Submit][Status][Discuss] Description Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地.除第m天外,每一天晚上Pine都必须在休息站过夜.所以,一段路必须在同一天中走完. Pine希望每一天走的路长度尽可能相近,所以