【笔记篇】斜率优化dp(二) SDOI2016征途
2018-01-25 17:14
288 查看
=======传=送=门=======
搜题目名会搜出很多奇怪的东西... 这个题目似乎有点毒?
比如在bzoj和loj上可以1A的代码上会在luogu TLE 2个点, 在cogs TLE 10个点 但是根据已有的资料来看数据都是一样的…
毒瘤评测姬毁我OI!!!
这个题的状态转移方程并不是很好推的说. 出题人让∗m2肯定是有目的的啊..
(比如不让乘m2我们可能会需要考虑乘m2最后再除掉之类的)
然后就化一波式子: 我们令sum表示n段路的总和.
m2s2=m2∑mi=1(xi−x¯)2m=m∑i=1m(xi−x¯)2=m∑i=1mx2i−m∑i=1m2xix¯+m∑i=1mx¯2=m∑i=1mx2i−(2∑i=1mxi)∗(m∗x¯)+m2(summ)2=m∑i=1mx2i−2sum2+sum2=m∑i=1mx2i−sum2
而m和sum2都是常数我们可以不管, 那就是要求最小化∑mi=1x2i.
所以令f[i][j]表示前i天走了前j段路, si表示前i段路的前缀和, 那就能写出状态转移方程:
f[i][j]=min{f[i−1][k]+(sj−sk)2}(k∈[1,j))
那很明显这个是O(n3)可以做的, 这样能拿到60pts了就.
但是想A的话 很明显要采用一种o(n2)的算法. 当然你要能O(n)甚至O(1)过也没啥问题…
那我们就要搬出斜率优化了. 我们继续化式子.
首先很明显第一维跟后面这一堆没啥关系, 那就不优化了, 也可以把这一维去掉, 到时候一滚动数组(其实不滚也能过)就行了.
那状态转移方程就可以改写成:
f[j]=min{f′[k]+(sj−sk)2}
然后继续化成y=kx+b的形式, f[j]=f′[k]+s2j−2sjsk+s2k
移项得f′[k]+s2k=2sjsk+f[j]−s2j
这样的话我们就可以正常的斜率优化了. 最后输出m∗f[n][m]−sum2就好啦~
不过要修一下边界条件.
- 比如第i天完全可以从i开始找, 总不可能回去找前面的路(这样也不会出现被0除错误),
- 然后f[1][x]显然应该等于s[x]2, 这样就可以了.
- 然后又是要开long long的题整天开long long还是挺烦的, 什么时候普及64位系统啊= =
然后就是代码: 并不知道究竟能不能AC 请谨慎复制!
被莫名的非主观因素的TLE卡掉好多下午的学(tui)习(fei)时间, 心情并不怎么好…
不过下雪了出去玩了一圈就非常爽了~ (⊙v⊙)嗯
所以编辑多行laTex公式的时候会出现一个写着数字的括号是什么鬼啊.. 难道是幽灵倒计时之类的东西???
搜题目名会搜出很多奇怪的东西... 这个题目似乎有点毒?
比如在bzoj和loj上可以1A的代码上会在luogu TLE 2个点, 在cogs TLE 10个点 但是根据已有的资料来看数据都是一样的…
毒瘤评测姬毁我OI!!!
这个题的状态转移方程并不是很好推的说. 出题人让∗m2肯定是有目的的啊..
(比如不让乘m2我们可能会需要考虑乘m2最后再除掉之类的)
然后就化一波式子: 我们令sum表示n段路的总和.
m2s2=m2∑mi=1(xi−x¯)2m=m∑i=1m(xi−x¯)2=m∑i=1mx2i−m∑i=1m2xix¯+m∑i=1mx¯2=m∑i=1mx2i−(2∑i=1mxi)∗(m∗x¯)+m2(summ)2=m∑i=1mx2i−2sum2+sum2=m∑i=1mx2i−sum2
而m和sum2都是常数我们可以不管, 那就是要求最小化∑mi=1x2i.
所以令f[i][j]表示前i天走了前j段路, si表示前i段路的前缀和, 那就能写出状态转移方程:
f[i][j]=min{f[i−1][k]+(sj−sk)2}(k∈[1,j))
那很明显这个是O(n3)可以做的, 这样能拿到60pts了就.
但是想A的话 很明显要采用一种o(n2)的算法. 当然你要能O(n)甚至O(1)过也没啥问题…
那我们就要搬出斜率优化了. 我们继续化式子.
首先很明显第一维跟后面这一堆没啥关系, 那就不优化了, 也可以把这一维去掉, 到时候一滚动数组(其实不滚也能过)就行了.
那状态转移方程就可以改写成:
f[j]=min{f′[k]+(sj−sk)2}
然后继续化成y=kx+b的形式, f[j]=f′[k]+s2j−2sjsk+s2k
移项得f′[k]+s2k=2sjsk+f[j]−s2j
这样的话我们就可以正常的斜率优化了. 最后输出m∗f[n][m]−sum2就好啦~
不过要修一下边界条件.
- 比如第i天完全可以从i开始找, 总不可能回去找前面的路(这样也不会出现被0除错误),
- 然后f[1][x]显然应该等于s[x]2, 这样就可以了.
- 然后又是要开long long的题整天开long long还是挺烦的, 什么时候普及64位系统啊= =
然后就是代码: 并不知道究竟能不能AC 请谨慎复制!
#include <cstdio> #include <cstring> const int N=3030;typedef long long LL; LL s ,q ,n,m,h,t;LL f ,g ; inline LL gn(LL a=0,char c=0){ for(;c<'0'||c>'9';c=getchar()); for(;c>47&&c<58;c=getchar())a=a*10+c-48;return a; } inline double slope(LL x,LL y){return 1.0*(g[x]+s[x]*s[x]-g[y]-s[y]*s[y])/(s[x]-s[y]);} int main(){ n=gn(); m=gn(); for(LL i=1;i<=n;++i) s[i]=s[i-1]+gn(),g[i]=s[i]*s[i]; for(LL i=2;i<=m;++i){h=0; t=0; q[h]=i-1; for(LL j=i;j<=n;++j){ while(h<t&&slope(q[h],q[h+1])<2*s[j]) ++h; f[j]=g[q[h]]+(s[j]-s[q[h]])*(s[j]-s[q[h]]); while(h<t&&slope(q[t],q[t-1])>slope(j,q[t])) --t; q[++t]=j; }::memcpy(g,f,sizeof(g)); }printf("%lld",f *m-s *s ); }
被莫名的非主观因素的TLE卡掉好多下午的学(tui)习(fei)时间, 心情并不怎么好…
不过下雪了出去玩了一圈就非常爽了~ (⊙v⊙)嗯
所以编辑多行laTex公式的时候会出现一个写着数字的括号是什么鬼啊.. 难道是幽灵倒计时之类的东西???
相关文章推荐
- CDQ分治与斜率优化DP——学习笔记
- 斜率优化dp 学习笔记
- 斜率优化DP学习笔记
- [斜率优化DP]【学习笔记】【更新中】
- 【笔记篇】斜率优化dp(一) HNOI2008玩具装箱
- 斜率优化dp学习笔记
- 【笔记篇】斜率优化dp(四) ZJOI2007仓库建设
- 【笔记篇】斜率优化dp(五) USACO08MAR土地购(征)买(用)Land Acquisition
- 【笔记篇】斜率优化dp(三) APIO特别行动队
- hdu 3507 斜率优化dp 入门学习
- [bzoj 1911][Apio 2010]特别行动队(斜率优化DP)
- bzoj 3437: 小P的牧场(斜率优化DP)
- Codeforces 643C Levels and Regions(斜率优化dp)
- hdu3507 Print Article 斜率优化dp
- 单调队列+斜率优化的DP
- POJ 3709 K-Anonymous Sequence (斜率优化DP)
- HDU 3045 Picnic Cows(斜率优化DP)
- HDU 3507 斜率优化dp
- HDU-3045 Picnic Cows 斜率优化DP
- 【DP】斜率优化