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

【BZOJ】【3437】小P的牧场

时间:2015-03-12 23:52:54      阅读:195      评论:0      收藏:0      [点我收藏+]

标签:

DP/斜率优化


  斜率优化基本题……等等,好像就没啥变化啊= =

  嗯目测这题跟仓库建设差不多?写题的时候倒是没想这么多……直接推了公式。

  $$f[i]=min\{f[j]+cal(j,i)+a[i]\}$$

  哦麻烦的还是这个$cal(j,i)$

  我们令$s[i]=\sum_{k=1}^{i}b[k]  c[i]=\sum_{k=1}^{i}(b[k]*k)$

  则有$cal(j,i)=(s[i]-s[j])*i-(c[i]-c[j])$(问我怎么想到的?这个嘛……像这题这种要求“阶梯形求和”的,基本都是利用矩形和$\sum a[i]*i=s[i]*i$ 以及 阶梯形和 $ \sum (a[i]*i) $两种前缀和加加减减拼凑出来的)

  所以有$f[i]=min\{ f[j]+(s[i]-s[j])*i-(c[i]-c[j])+a[i] \}$

  单调性证明:$( j > k )$

\[ \begin{aligned} f[j]+(s[i]-s[j])*i-(c[i]-c[j])+a[i] &< f[k]+(s[i]-s[k])*i-(c[i]-c[j])+a[i] \\ f[j]-f[k]+c[j]-c[k] &< i*(s[j]-s[k]) \\ \frac{f[j]-f[k]+c[j]-c[k]}{s[j]-s[k]} &< i \end{aligned} \]

技术分享
 1 /**************************************************************
 2     Problem: 3437
 3     User: Tunix
 4     Language: C++
 5     Result: Accepted
 6     Time:2096 ms
 7     Memory:44240 kb
 8 ****************************************************************/
 9  
10 //BZOJ 3437
11 #include<cmath>
12 #include<vector>
13 #include<cstdio>
14 #include<cstring>
15 #include<cstdlib>
16 #include<iostream>
17 #include<algorithm>
18 #define rep(i,n) for(int i=0;i<n;++i)
19 #define F(i,j,n) for(int i=j;i<=n;++i)
20 #define D(i,j,n) for(int i=j;i>=n;--i)
21 #define pb push_back
22 using namespace std;
23 int getint(){
24     int v=0,sign=1; char ch=getchar();
25     while(ch<0||ch>9){ if (ch==-) sign=-1; ch=getchar();}
26     while(ch>=0&&ch<=9){ v=v*10+ch-0; ch=getchar();}
27     return v*=sign;
28 }
29 const int N=1e6+10;
30 typedef long long LL;
31 /******************tamplate*********************/
32 LL a[N],b[N],c[N],s[N],f[N];
33 int q[N],l,r,n;
34 inline double slop(int k,int j){
35     return double(f[j]-f[k]+c[j]-c[k])/double(s[j]-s[k]);
36 }
37 int main(){
38     n=getint();
39     F(i,1,n) a[i]=getint();
40     F(i,1,n){
41         b[i]=getint();
42         s[i]=s[i-1]+b[i];
43         c[i]=c[i-1]+b[i]*i;
44     }
45     F(i,1,n){
46         while(l<r && slop(q[l],q[l+1])<i)l++;
47         int t=q[l];
48         f[i]=f[t]+(s[i]-s[t])*i-c[i]+c[t]+a[i];
49         while(l<r && slop(q[r-1],q[r])>slop(q[r],i))r--;
50         q[++r]=i;
51     }
52     printf("%lld\n",f[n]);
53     return 0;
54 }
View Code

 

【BZOJ】【3437】小P的牧场

标签:

原文地址:http://www.cnblogs.com/Tunix/p/4333852.html

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