码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 1096 ZJOI2007 仓库设计 斜率优化dp

时间:2016-01-05 20:54:25      阅读:220      评论:0      收藏:0      [点我收藏+]

标签:

   太高兴了,这是我第一次自己独立思考的斜率优化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毫秒)

 1 #include<cstdio>
 2 #include<iostream>
 3 #define rep(i,j,k) for(int i = j; i <= k; i++)
 4 #define maxn 1000005
 5 #define ll long long
 6 using namespace std;
 7 
 8 int read()
 9 {
10     int s = 0, t = 1; char c = getchar();
11     while( !isdigit(c) ){
12         if( c == - )t = -1; c = getchar();
13     }
14     while( isdigit(c) ){
15         s = s * 10 + c -0; c = getchar();
16     }
17     return s * t;
18 }
19 
20 ll tot[maxn] = {0}, f[maxn] = {0}, c[maxn] = {0}, p[maxn] = {0}, x[maxn] = {0};
21 int q[maxn] = {0};
22 
23 ll S(int k,int j)
24 {
25     return f[j] - f[k] + p[j] * x[j] - p[k] * x[k] + tot[k] - tot[j];
26 }
27 
28 ll G(int k,int j)
29 {
30     return p[j] - p[k];
31 }
32 
33 int main()
34 {
35    int n = read();
36    rep(i,1,n){
37          x[i] = read(), p[i] = read(), c[i] = read();  p[i] += p[i-1];
38    }
39    rep(i,1,n){
40         tot[i] = p[i-1] * (x[i]-x[i-1]) + tot[i-1];
41    }
42    int l = 0, r = 0; q[r] = 0;
43    rep(i,1,n){
44          while( l < r && S(q[l+1],q[l]) >= G(q[l+1],q[l]) * x[i] ) l++;
45          int j = q[l];
46          f[i] = f[j] + tot[i] - tot[j] + c[i] - p[j] * (x[i]-x[j]);
47          while( l < r && S(q[r],q[r-1]) * G(i, q[r]) >= S(i,q[r]) * G(q[r],q[r-1]) ) r--;
48       q[++r] = i;
49    }
50    cout<<f[n]<<endl;
51    return 0;
52 }

 

BZOJ 1096 ZJOI2007 仓库设计 斜率优化dp

标签:

原文地址:http://www.cnblogs.com/83131yyl/p/5103544.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!