单调栈 BZOJ2364 城市美化

2364: 城市美化

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 182  Solved: 42
[Submit][Status][Discuss]

Description

城市A需要美化市容市貌,现在有n个楼房排成一列,每个楼房的高都在[1,1000]的范围内。市长请了一批工程师来对其中一些楼房进行修建,使楼房高度得到上升(不能让楼房高度下降),对一栋楼房修建,使其高度上升x,需要x2的费用。

当所有修建完成后,我们把相邻两楼高度的绝对值乘以c(0<=c<=1000),得到的就是城市损失的钱,我们把它同样看作是费用。现在想请你合理安排修建楼房的方案,使得所需费用最小。

Input

第一行两个数n和c。

接下来n行,每行一个数,表示每栋楼的高度。

Output

仅一行一个数,表示最小所需的费用。

Sample Input

5 5

2

2

1

6

8

Sample Output

31

HINT

数据范围

对于100%的数据,1<=n<=50000

f[i]表示前i个且最后一段与 i-1 相同的最小代价。

可以得到一些性质:(1) 当一个楼房两边都比它高,或者一个楼房处于边界,那么将它向上调整才能使代价减小;

         (2) 若一个楼房两边都高于它,且最后它向上调整了,则两侧的楼房高度都应与它相同,直到有比它更高的为止。

则可以维护一个单调递减的楼房转移,ask用于二次函数求极值。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 int n,c,top;
 8 int stack[50010];
 9 long long h[50010],sum[50010],sumpow[50010],f[50010];
10 long long ask(long long a,long long b,long long d,long long mn,long long mx){
11     double t=(double)-b/(2*a);
12     long long x;
13     if(mn<=t&&t<=mx) x=round(t);
14     if(mn>t) x=mn;
15     if(mx<t) x=mx;
16     return a*x*x+b*x+d;
17 }
18 long long solve(int ll,int rr,long long mn){
19     if(ll+1==rr) return (ll==1||rr==n+2)?0:abs(h[rr]-h[ll])*c;
20     long long a=rr-ll-1,b=-2*(sum[rr-1]-sum[ll]),d=sumpow[rr-1]-sumpow[ll];
21     long long mx=min(h[ll],h[rr]);
22     if(ll!=1) b-=c,d+=c*h[ll];
23     if(rr!=n+2) b-=c,d+=c*h[rr];
24     return ask(a,b,d,mn,mx);
25 }
26 long long work(){
27     stack[++top]=1;
28     for(int i=2;i<=n+2;i++){
29         f[i]=1e60;
30         int end=0;
31         while(top&&h[stack[top]]<h[i]){
32             f[i]=min(f[i],f[stack[top]]+solve(stack[top],i,end));
33             end=h[stack[top--]];
34         }
35         f[i]=min(f[i],f[stack[top]]+solve(stack[top],i,end));
36         stack[++top]=i;
37     }
38     return f[n+2];
39 }
40 int main(){
41     scanf("%d%d",&n,&c);
42     h[1]=h[n+2]=1e60;
43     for(int i=1;i<=n;i++) scanf("%d",&h[i+1]);
44     for(int i=1;i<=n+2;i++){
45         sum[i]=sum[i-1]+h[i];
46         sumpow[i]=sumpow[i-1]+h[i]*h[i];
47     }
48     printf("%lld",work());
49     return 0;
50 }
时间: 2024-08-11 09:44:46

单调栈 BZOJ2364 城市美化的相关文章

hdu5033 Building (单调栈+)

http://acm.hdu.edu.cn/showproblem.php?pid=5033 2014 ACM/ICPC Asia Regional Beijing Online B 1002 Building Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 0    Accepted Submission(s): 0Special

小结:单调栈 &amp; 单调队列

概要: 对于维护信息具有单调性的性质或者问题可以转化为具有单调性质的模型的题,我们可以考虑用单调栈或单调队列. 技巧及注意: 技巧很多,只要能将问题转化为单调性问题,就好解决了. 当维护固定长度的单调区间,我们考虑用单调队列,如[BZOJ]3314: [Usaco2013 Nov]Crowded Cows(单调队列) 单调栈维护长度时要进行及时更新,例如:[BZOJ]3039: 玉蟾宫(DP/单调栈) 假设完美状态后再进行减法原理,例如:[BZOJ]1628 && 1683: [Usaco

HDU 5033 Building(北京网络赛B题) 单调栈 找规律

做了三天,,,终于a了... 11724203 2014-09-25 09:37:44 Accepted 5033 781MS 7400K 4751 B G++ czy Building Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 1257    Accepted Submission(s): 358 Special Judg

BZOJ_1628_[Usaco2007_Demo]_City_skyline_(单调栈)

描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1628 给出\(n\)个距形的影子,问最少是多少个建筑的?(建筑的影子可以重叠). 分析 用单调栈维护一下. 栈内是可能"延续"到当前位置的之前的影子.那么显然比当前位置高的不可能.如果有和当前位置等高的影子,就延续过来,就可以少一个建筑,否则,就向栈里加入当前位置高度的影子. 1 #include <bits/stdc++.h> 2 using namespace st

【CF671E】Organizing a Race 单调栈+线段树

[CF671E]Organizing a Race 题意:n个城市排成一排,每个城市内都有一个加油站,赛车每次经过第i个城市时都会获得$g_i$升油.相邻两个城市之间由道路连接,第i个城市和第i+1个城市之间的道路长度为$w_i$,走一单位的路要花1升油.你想在某两个城市之间举办一场锦标赛.如果你选择的两个城市分别是a和b(a<b),则具体过程如下: 1. 赛车从a开始往右走一直走到b,走过城市时会在加油站加油,走过道路时会消耗油,且一开始时就已经在a处加完油了.你需要满足赛车能有足够的油能从a

[51nod 1288]汽油补给(ST表+单调栈)

[51nod 1288]汽油补给(ST表+单调栈) 题面 有(N+1)个城市,0是起点N是终点,开车从0 -> 1 - > 2...... -> N,车每走1个单位距离消耗1个单位的汽油,油箱的容量是T.给出每个城市到下一个城市的距离D,以及当地的油价P,求走完整个旅途最少的花费.如果无法从起点到达终点输出-1. 分析 贪心考虑,当我们到达一个城市x的时候,我们下一个到的城市应该是在x加满油的情况下,能到达的油价比x低的城市.如果每个加油城市之间的路都这样走,那么最后的价钱一定是最小的.

(单调栈)poj-2559 Largest Rectangle in a Histogram

A histogram is a polygon composed of a sequence of rectangles aligned at a common base line. The rectangles have equal widths but may have different heights. For example, the figure on the left shows the histogram that consists of rectangles with the

【单调栈】hdu1506 Largest Rectangle in a Histogram

单调栈的介绍及一些基本性质 http://blog.csdn.net/liujian20150808/article/details/50752861 依次把矩形塞进单调栈,保持其单增,矩形中的元素是一个三元组,存储其位置,高度,以及以其为高度的情况下,大矩形的左边界最多扩展到哪里. 每次将新的元素塞进栈的时候,其左边界就是其左侧第一个小于它的矩形的位置+1. 然后,每个矩形出栈的时候,记录其右边界为当前往栈里面塞的矩形的位置-1,然后更新答案即可. 注意最后把所有的矩形出栈,更新答案. #in

BZOJ 3238 AHOI 2013 差异 后缀数组+单调栈

题目大意: 思路:一看各种后缀那就是后缀数组没跑了. 求出sa,height之后就可以乱搞了.对于height数组中的一个值,height[i]来说,这个值能够作为lcp值的作用域只在左边第一个比他小的位置到右边第一个比他小的位置.这个东西很明显可以倍增RMQ+二分/单调栈. 之后就是数学题了 Σlen[Ti] + len[Tj] = (len + 1) * len * (len - 1),之后吧所有求出来的Σ2 * lcp(Ti,Tj)减掉就是答案. 记得答案开long long CODE: