您的位置:首页 > 其它

【笔记篇】斜率优化dp(三) APIO特别行动队

2018-01-26 07:13 330 查看
旁听了一波给舒老师和学弟的pkuwc面试讲座…

这里有一段隐身的吐槽, 请反白观看. 不想看的跳过这一段看似空白的东西就好了…

刚开始ATP学姐给我们讲了自己面试的时候的事情..描绘了一下当时面试的场面和当时问的问题…ATP学姐太可爱了OvO可能准备的也不是很充足 用了好多的”然后” “就是”之类的, 自己也在吐槽, 老师后来也槽来着, 不过还是超可爱n(≧▽≦)n旁边老师在记录, 尤其记下了一个什么”你认为学习信息男生和女生有什么区别?”的问题..可是这种问题怎么可能问男生啊讲道理, 然后学姐讲完之后就是shallwe大爷来讲, shallwe大爷还准备了稿子, 然后就讲了一些面基技巧.. 但是也是比较老生常谈的东西, 之前参加各种各样的风采大赛回答问题的时候也就是那一套之类的 小时候还能做到, 现在反而越来越不行了.. 然后讲了各种各样的问题, 说是问的问题都在blog里面.. 老师还说要blog的地址来给学弟学妹什么的(那也就是包括我们咯), 但是听完回来一看这blog里的东西能给老师看?! 各种吐槽甚至还有吐槽面试培训的.. 然后他们就回去学习了= =

老师就开始种讲评, 还让两个人分别回答了上面说的男女区别问题 然后两个都做出了比较”片面”的回答, 老师就说要往什么三个方面想之类的说了一堆, 反正就是不怼人的同时优雅地装逼的技巧, 什么在北大不说清华比北大强之类的, 说了确定不是石乐志么= =然后再就是”你有什么缺点”, 听说年年问..大家准备好的答案都能倒着背了好么就说要找个”不是缺点的缺点”, 然后两个人都说自己比较执着啊… 就不能找点有创意的么←←, 感觉全世界都有执着得有点傻这个缺点… 要我的话可能会说自己好奇心过强? 反正就这么着吧. 然后还有什么进门关门鞠躬瞅瞅有没有废纸倒拖把什么的… 反正就是一些鸡汤文里描写的面试的细节问题, 还有着装问题, 我觉得只要不是明显违和的穿女装应该都不是什么大问题吧←←对没错哪怕是可爱的男孩纸穿女装其实也是可以哒~(≧▽≦)/~两个人又练了一波关门鞠躬之类的 终于煎熬地熬过去了.. 然后赶紧去了个厕所 毕竟半下午+半晚上没有去了.. 回来之后就调这个题 不过很快就调A了这还比较和善..嗯 主要原因是这次的luogu没有出锅...

===我===是===一===条===分===割===线===我===也===是===一===扇===传===送===门===

继续吐槽, 不过这次跟题目有关了.. 听完回来就继续写这道题啊…

这道题显然支持O(n)的做法, (感觉1e6的话套个log就不是很靠谱了)

那就是要优化, 就是要化式子嘛..然后刚开始以为这个题是

∑i=1n(ax2i+bxi+c)=a∑i=1nx2i+bsn+n∗c之后直接输出a∗f[n]+b∗s[n]+n∗c的大水题,

但是发现好像样例差了好多好多…结果发现自己快读没读负数…

然后改完之后输出负数了… 手玩了一下发现好像这个n∗c的n好像不一定是题目里给的n…

那就不能这么化式子了, 就开始重新化.. 还是得从状态转移方程入手…

f[i]=max{f[j]+a(s[i]−s[j])2+b(s[i]−s[j])+c}(j∈[1,i))

然后去括号

f[i]=f[j]+as[i]2−2as[i]s[j]+as[j]2+bs[i]−bs[j]+c

移项能得到

f[j]+as[j]2−bs[j]=2as[i]s[j]+f[i]−(as[i]2+bs[i]+c)

由于题目中已经给了−5<a<−1, 所以斜率一定是<0的, 而f[j]+as[j]2−bs[j]直观上很明显是递减的. 我们考虑凸性对结果的影响.



我们考虑中间的点在位于两个斜率中间(大于大斜率小于小斜率显然不优就不考虑了)的情况.

发现如果是位于下凸壳的点是不优的, 而位于上凸壳的点是优的, 我们就要维护一个上凸壳.

而这里的斜率2as[i]显然是递减的(绝对值递增), 所以



如果一个斜率一旦已经小于(绝对值大)于队首的边, 那么队首的点在以后也不会优了 我们让队首出队即可.

依然是维护一个单调队列.

然后就没有了. 代码: 1A了哈哈哈哈 (放肆地笑ing…)

#include <cstdio>
const int N=16+6;
typedef long long LL;
LL f
,s
; int q
,h,t,a,b,c,n;
inline int gn(int a=0,char c=0,int f=1){
for(;(c<48||c>57)&&c!='-';c=getchar());if(c=='-')f=-1,c=getchar();
for(;c>='0'&&c<='9';c=getchar()) a=a*10+c-'0'; return a*f;
}
inline double slope(int x,int y){
return 1.0*(f[x]+a*s[x]*s[x]-b*s[x]-f[y]-a*s[y]*s[y]+b*s[y])/(s[x]-s[y]);
}
int main(){ n=gn(); a=gn(); b=gn(); c=gn();
for(int i=1;i<=n;++i) s[i]=s[i-1]+gn();
for(int i=1;i<=n;++i){
while(h<t&&slope(q[h],q[h+1])>=2*a*s[i]) ++h;
f[i]=f[q[h]]+a*(s[i]-s[q[h]])*(s[i]-s[q[h]])+b*(s[i]-s[q[h]])+c;
while(h<t&&slope(q[t],q[t-1])<=slope(q[t],i)) --t;
q[++t]=i;
} printf("%lld",f
);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: