bzoj1911 特别行动队 动态规划斜率优化
2016-01-24 21:59
176 查看
一道比较复杂的斜率优化,如果对于j<k,且对于i来说k比j更优,列出方程
f[j]+a*(sum[i]-sum[j])^2+b*(sum[i]-sum[j])+c<f[k]+a*(sum[i]-sum[k])^2+b*(sum[i]-sum[k])+c,化简得到:
sum[i]>(f[j]+a*sum[j]^2-b*sum[j]-(f[k]+a*sum[k]^2-b*sum[k]))/(2*a*(sum[j]-sum[k]))。
将右边作为斜率k(j,k)则k为下凸函数(就是后一项比前一项大),单调队列维护这个函数即可。
AC代码如下:
by lych
2016.1.24
f[j]+a*(sum[i]-sum[j])^2+b*(sum[i]-sum[j])+c<f[k]+a*(sum[i]-sum[k])^2+b*(sum[i]-sum[k])+c,化简得到:
sum[i]>(f[j]+a*sum[j]^2-b*sum[j]-(f[k]+a*sum[k]^2-b*sum[k]))/(2*a*(sum[j]-sum[k]))。
将右边作为斜率k(j,k)则k为下凸函数(就是后一项比前一项大),单调队列维护这个函数即可。
AC代码如下:
#include<iostream> #include<cstdio> #include<cstring> #define N 1000005 #define ll long long using namespace std; int n,q ; ll A,B,C,s ,f ,c ; int read(){ int x=0; char ch=getchar(); while (ch<'0' || ch>'9') ch=getchar(); while (ch>='0' && ch<='9'){ x=x*10+ch-'0'; ch=getchar(); } return x; } double slp(int x,int y){ return (double)(c[x]-c[y])/2/A/(s[x]-s[y]); } int main(){ scanf("%d%lld%lld%lld",&n,&A,&B,&C); int i; for (i=1; i<=n; i++) s[i]=s[i-1]+read(); int head=1,tail=1; q[1]=0; for (i=1; i<=n; i++){ while (head<tail && slp(q[head],q[head+1])<=s[i]) head++; ll tmp=s[i]-s[q[head]]; f[i]=f[q[head]]+A*tmp*tmp+B*tmp+C; c[i]=f[i]+A*s[i]*s[i]-B*s[i]; while (head<tail && slp(q[tail],i)<=slp(q[tail-1],q[tail])) tail--; q[++tail]=i; } printf("%lld\n",f ); return 0; }
by lych
2016.1.24
相关文章推荐
- 基础训练 完美的代价(贪心算法)
- apue.h 源码
- 如何解决PHP里大量数据循环时内存耗尽的问题
- 一张图告诉你,只会Node.JS还不够!
- 欢迎使用CSDN-markdown编辑器
- CefSharp(三)屏蔽右键菜单
- Facebook是如何做自动化测试的?
- C++类型转换
- 测试用例设计白皮书--因果图方法
- 错误推测法
- 【BZOJ2330】 [SCOI2011]糖果
- 大一下学期的自我目标,上学期的小总结
- asp.net网站500.19错误的解决办法
- tarjan算法应用 割点 桥 双连通分量
- tarjan算法应用 割点 桥 双连通分量
- PHP——简单的表单提交
- inotify+rsync目录实时同步
- 男宝女宝如厕训练有不同,你做对了吗?
- 红黑树的C++实现
- 【实战Java高并发程序设计 4】数组也能无锁:AtomicIntegerArray