首页 > 学院 > 开发设计 > 正文

BZOJ 3437 小P的牧场 斜率优化

2019-11-08 19:47:18
字体:
来源:转载
供稿:网友
#include <cstdio>#include <cstring>#include <algorithm>#include <cstring>#include <cmath>#define MAXN 1000005#define N 100#define LL long long#define INF 1000000005#define max(a,b) ((a)>(b)?(a):(b))#define min(a,b) ((a)<(b)?(a):(b))using namespace std;const double eps = 1e-8;/* http://www.lydsy.com/JudgeOnline/PRoblem.php?id=3437 Pi为每个牧场放牧数量 Ci为在i点建立控制点的花费 Si为P的前缀和 Bi为i*Pi的前缀和 考虑假如i+1到j的牧场都在0号位置时 花费为(Si-Sj)*i; 但它们不在0号位置 所以每个物品可以少花费Pi*i 因此 在i和j建立控制点的代价为 (Si-Sj)*i-(Bi-Bj) Fi=min{Fj+(Si-Sj)*i-(Bi-Bj)}+Ci Sj*i+Fi+Bi-Si*i=Fj+Bj k=i,b=Fi+Bi-Si*i-Ci x=Sj,y=Fj+Bj 斜率优化即可*/LL read(){ LL t=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){t=t*10+ch-'0';ch=getchar();} return t*f;}LL n,l=1,r=0;LL f[MAXN],q[MAXN],b[MAXN],c[MAXN],p[MAXN],x[MAXN],s[MAXN];double getk(int i,int j){ return (double)(f[i]+b[i]-f[j]-b[j])/(double)(s[i]-s[j]);}int main(){ n=read(); for(int i=1;i<=n;i++) c[i]=read(); for(int i=1;i<=n;i++) p[i]=read(); for(int i=1;i<=n;i++) s[i]=s[i-1]+p[i],b[i]=b[i-1]+i*p[i]; q[++r]=0; for(int i=1;i<=n;i++) { while(l<r&&getk(q[l],q[l+1])<i) l++; int j=q[l]; f[i]=f[j]+(s[i]-s[j])*i-(b[i]-b[j])+c[i]; while(l<r&&getk(i,q[r])<getk(q[r],q[r-1])) r--; q[++r]=i; } printf("%lld",f[n]); return 0;}
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表