P2900 [USACO08MAR]土地征用Land Acquisition

来源:互联网 发布:算法新解刘新宇pdf 编辑:程序博客网 时间:2024/05/16 09:40

Description

农夫John准备扩大他的农场,他正在考虑N (1 <= N <= 50,000) 块长方形的土地. 每块土地的长宽满足(1 <= 宽 <= 1,000,000; 1 <= 长 <= 1,000,000). 每块土地的价格是它的面积,但FJ可以同时购买多快土地. 这些土地的价格是它们最大的长乘以它们最大的宽, 但是土地的长宽不能交换. 如果FJ买一块3×5的地和一块5×3的地,则他需要付5×5=25. FJ希望买下所有的土地,但是他发现分组来买这些土地可以节省经费. 他需要你帮助他找到最小的经费.

Input

* 第1行: 一个数: N

* 第2..N+1行: 第i+1行包含两个数,分别为第i块土地的长和宽

Output

* 第一行: 最小的可行费用.

Sample Input

4
100 1
15 15
20 5
1 100
输入解释:
共有4块土地.

Sample Output

500

HINT

FJ分3组买这些土地: 第一组:100×1, 第二组1×100, 第三组20×5 和 15×15 plot. 每组的价格分别为100,100,300, 总共500.


代码:

#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int maxn=1000000+5;int read(){int x=0,f=1;char ch;ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}return x*f;}int n,a,b,c;int w[maxn],q[maxn];long long s[maxn],f[maxn];long long g(int i){return a*s[i]*s[i]+b*s[i];}long long h(int j){return f[j]+a*s[j]*s[j]-b*s[j];}double slope(int j1,int j2){return (h(j1)-h(j2))/(2.0*a*(s[j1]-s[j2]));}long long js(int x){return a*x*x+b*x+c;}int main(){int i;n=read();a=read();b=read();c=read();for(i=1;i<=n;i++)w[i]=read();for(i=1;i<=n;i++)s[i]=s[i-1]+w[i];int h=1,p=0;q[++p]=0;for(i=1;i<=n;i++){while(p>h&&slope(q[h],q[h+1])<=s[i]) h++;int t=q[h];f[i]=f[t]+js(s[i]-s[t]);while(p>h&&slope(q[p],i)<slope(q[p-1],q[p])) p--;q[++p]=i;}printf("%lld",f[n]);return 0;}