bzoj3437 小P的牧场

来源:互联网 发布:sql 统计字符串长度 编辑:程序博客网 时间:2024/05/01 10:22

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3437

题目大意(自己去看吧↑,我懒了~

这道题的题意跟防御准备有点像的嗯。

===============================================

题解:

斜率优化

这个我自己搞不出方程QvQ好菜啊!于是我去问HYC大学霸怎么处理了嘿嘿嘿..

设sum[i]为前缀和,sm[i]为b[i]*(n-i)的前缀和,就是b[i]*(n-i)就表示该点放养量*这个点到末尾的距离呸牧场数目。[讲真。。起名无能sm就sm嘛= =]

f[i]表示在i建个控制站并搞完前i个牧场的最小花费

弄个sm之后我就会写方程啦~啦啦啦(- -

f[i]=f[j]+sm[j+1]-sm[i]-(sum[i-1]-sum[j])*(n-i)+a[i];

于是发现我自己好zz,如果不理解就画一下?啊很好理解的是吧~

-(n-i)*sum[j]+f[i]=f[j]+sm[j+1]-sm[i]-sum[i-1]*(n-i)+a[i];

日常化成截距式啦然后就好了。注意一下longlong咯

#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<iostream>using namespace std;typedef long long LL;#define maxn 1010000int q[maxn];LL sum[maxn],sm[maxn],f[maxn],a[maxn],b[maxn];double X(int j){return sum[j];}double Y(int j){return f[j]+sm[j+1];}double slop(int j1,int j2){return (Y(j2)-Y(j1))/(X(j2)-X(j1));}int main(){int n,i,l,r;scanf("%d",&n);sum[0]=0;memset(f,0,sizeof(f));for (i=1;i<=n;i++) scanf("%lld",&a[i]);for (i=1;i<=n;i++){scanf("%lld",&b[i]);sum[i]=sum[i-1]+b[i];}sm[n]=0;for (i=n-1;i>=1;i--) sm[i]+=sm[i+1]+b[i]*(n-i);l=1;r=1;q[1]=0;for (i=1;i<=n;i++){while (l<r && slop(q[l],q[l+1])<i-n) l++;int j=q[l];f[i]=f[j]+sm[j+1]-sm[i]-(sum[i-1]-sum[j])*(n-i)+a[i];while (l<r && slop(q[r-1],q[r])>slop(q[r],i)) r--;q[++r]=i;}printf("%lld",f[n]);return 0;}


0 0
原创粉丝点击