BZOJ 1096 ZJOI2007 仓库设计 斜率优化dp
2016-01-05 19:20
375 查看
太高兴了,这是我第一次自己独立思考的斜率优化dp,从头到尾都是自己想的。(相信自己,能行的,不过也做了40分钟了)。 这道题目还好吧! 看到之后第一反应是想设从工厂0运到工厂i 总共需要 tot[i] 的费用, 用 p[i] 表示从山顶到工厂 i 总共的产品数, 再用 x[i] 表示从工厂0到工厂 i 的距离, 那么状态转移方程就是 f[i] = min{f[j] + tot[i] - tot[j] - p[j] * (x[i] - x[j] ) + c[i] } ,很明显由于数据有 n <= 1000000 不能 n ^ 2 的朴素算法, 要进行优化。 先看一下状态转移方程, 除了 f[j] 不定之外, 其他的在数据给出时都已确定(换句话说,满足无后效性,只要保证之前处理f[i]时,f[i]是最小就好),可以考虑斜率优化。
那么设 j < k , 目前正在处理 f[i]; 如果 j 比 k 差的话, 那么 f[j] + tot[i] - tot[j] - p[j] * (x[i] - x[j] ) >= f[k] + tot[i] - tot[k] - p[k] * (x[i] - x[k])
移项化简得当 f[j] - f[k] - tot[j] + tot[k] + p[j] * x[j] - p[k] * x[k] >= x[i] * (p[j] - p[k]) 时 j 比 k 差。
又因为求的是最小值所以要维护一个下凸函数。加油,努力。(1700毫秒)
那么设 j < k , 目前正在处理 f[i]; 如果 j 比 k 差的话, 那么 f[j] + tot[i] - tot[j] - p[j] * (x[i] - x[j] ) >= f[k] + tot[i] - tot[k] - p[k] * (x[i] - x[k])
移项化简得当 f[j] - f[k] - tot[j] + tot[k] + p[j] * x[j] - p[k] * x[k] >= x[i] * (p[j] - p[k]) 时 j 比 k 差。
又因为求的是最小值所以要维护一个下凸函数。加油,努力。(1700毫秒)
#include<cstdio> #include<iostream> #define rep(i,j,k) for(int i = j; i <= k; i++) #define maxn 1000005 #define ll long long using namespace std; int read() { int s = 0, t = 1; char c = getchar(); while( !isdigit(c) ){ if( c == '-' )t = -1; c = getchar(); } while( isdigit(c) ){ s = s * 10 + c -'0'; c = getchar(); } return s * t; } ll tot[maxn] = {0}, f[maxn] = {0}, c[maxn] = {0}, p[maxn] = {0}, x[maxn] = {0}; int q[maxn] = {0}; ll S(int k,int j) { return f[j] - f[k] + p[j] * x[j] - p[k] * x[k] + tot[k] - tot[j]; } ll G(int k,int j) { return p[j] - p[k]; } int main() { int n = read(); rep(i,1,n){ x[i] = read(), p[i] = read(), c[i] = read(); p[i] += p[i-1]; } rep(i,1,n){ tot[i] = p[i-1] * (x[i]-x[i-1]) + tot[i-1]; } int l = 0, r = 0; q[r] = 0; rep(i,1,n){ while( l < r && S(q[l+1],q[l]) >= G(q[l+1],q[l]) * x[i] ) l++; int j = q[l]; f[i] = f[j] + tot[i] - tot[j] + c[i] - p[j] * (x[i]-x[j]); while( l < r && S(q[r],q[r-1]) * G(i, q[r]) >= S(i,q[r]) * G(q[r],q[r-1]) ) r--; q[++r] = i; } cout<<f <<endl; return 0; }
相关文章推荐
- jmeter学习 七
- HDU 2084 数塔(DP)
- flashback闪回总结
- 豆瓣收藏的功能数据库
- SysV和BSD启动风格的比较
- js中判断一个对象的类型的种种方法
- java成员变量与局部变量
- Itellij IDEA启动报错
- Common JS Function
- JFinal学习-Excel导出
- 面试题
- c++ c# 类型转换
- Collections.sort排序
- CSS hack大全(区分浏览器)
- OC方法,数字转换成汉字
- 使用CocoaPods配置第三方类库
- Android can only be built by versions 3.81 and 3.82
- utf8格式源代码中的字符串,默认都会当作char来处理,除非用L""符号来修饰
- CRM2013电子邮件路由器配置问题
- Unity5.2.1上Android真机调试环境配置