## bzoj 3437 斜率优化DP

写题解之前首先要感谢妹子。

比较容易的斜率DP，设sum[i]=Σb[j]，sum_[i]=Σb[j]*j，w[i]为第i个建立，前i个的代价。

那么就可以转移了。

/**************************************************************
Problem: 3437
Language: C++
Result: Accepted
Time:3404 ms
Memory:39872 kb
****************************************************************/

#include <cstdio>
#define maxn 1000010
#define LL long long

using namespace std;

LL n;
LL a[maxn],sum[maxn],sum_[maxn];
LL que[maxn];
LL w[maxn];

LL get(LL i) {
return (w[i]+sum_[i]);
}

int main() {
scanf("%lld",&n);
for (LL i=1;i<=n;i++) scanf("%lld",&a[i]);
for (LL i=1;i<=n;i++) scanf("%lld",&sum[i]);
for (LL i=1;i<=n;i++) sum_[i]=i*sum[i];
for (LL i=1;i<=n;i++) sum[i]+=sum[i-1],sum_[i]+=sum_[i-1];
LL h(1),t(1);
for (LL i=1;i<=n;i++) {
while ((t-h>0)&&((sum[que[h]]-sum[que[h+1]])*i<=(w[que[h]]+sum_[que[h]]-w[que[h+1]]-sum_[que[h+1]]))) h++;
w[i]=w[que[h]]+(sum[i]-sum[que[h]])*i-(sum_[i]-sum_[que[h]])+a[i];
//w[i]=w[que[h]]+sum_[que[h]]-i*sum[que[h]]+i*sum[i]+a[i]-sum_[i];
while ((t>h)&&((get(que[t-1])-get(i))*(sum[que[t-1]]-sum[que[t]])<=(get(que[t-1])-get(que[t]))*(sum[que[t-1]]-sum[i]))) t--;
/*
while ((t-h>0)&&(
(w[que[t-1]]+sum_[que[t-1]]-w[i]-sum_[i])*(sum[que[t-1]]-sum[que[t]])<=
(w[que[t-1]]+sum_[que[t-1]]-w[que[t]]-sum_[que[t]])*(sum[que[t-1]]-sum[i]))
) t--;
*/
que[++t]=i;
}
printf("%lld\n",w[n]);
return 0;
}

posted on 2014-05-08 09:56  BLADEVIL  阅读(450)  评论(0编辑  收藏  举报