您的位置:首页 > 其它

bzoj1597[Usaco2008 Mar]土地购买 斜率优化dp

2017-12-26 20:38 471 查看

1597: [Usaco2008 Mar]土地购买

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 5524  Solved: 2074
[Submit][Status][Discuss]

Description

农夫John准备扩大他的农场,他正在考虑N (1 <= N <= 50,000) 块长方形的土地. 每块土地的长宽满足(1 <= 宽 < = 1,000,000; 1 <= 长 <= 1,000,000). 每块土地的价格是它的面积,但FJ可以同时购买多快土地. 这些土地的价 格是它们最大的长乘以它们最大的宽, 但是土地的长宽不能交换. 如果FJ买一块3x5的地和一块5x3的地,则他需要 付5x5=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
FJ分3组买这些土地:
第一组:100x1,
第二组1x100,
第三组20x5 和 15x15 plot.
每组的价格分别为100,100,300, 总共500.

HINT

 

Source

Gold

 

按长从小到大sort 去掉包含关系
那么就可以得到长递增宽递减的长方形序列
b为宽 a为长
dp[i]=dp[j]+(a[i]*b[j+1])

决策单调性很显然 简单的证明一下
设k<j && j的决策比k优
dp[j]+a[i]*b[j+1]<=dp[k]+a[i]*b[k+1]

对于任意t>i a[t]>a[i] 设a[t]=a[i]+v
若要证明决策单调 需证明dp[j]+a[t]*b[j+1]<=dp[k]+a[i]*b[k+1]
把a[t]代入得 dp[j]+a[i]+b[j+1]+v*b[j+1]<=dp[k]+a[i]*b[k+1]+v*b[k+1]
b[j+1]<=b[k+1]所以上式成立
决策具有单调性
证毕

dp[j]+(a[i]*b[j+1])<=dp[k]+(a[i]*b[k+1])

(dp[j]-dp[k])/(b[k+1]-b[j+1])<=a[i]

 

#include<cstdio>
#include<algorithm>
#include<queue>
#define ll long long
#define N 500005
using namespace std;
ll dp
;int q
;
struct square{ll l,w;bool operator <(const square &b)const{return l==b.l?w<b.w:l<b.l;}}a
;
ll G(int j,int k){return dp[j]-dp[k];}ll S(int j,int k){return a[k+1].w-a[j+1].w;}
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d%d",&a[i].l,&a[i].w);
int tot=0;sort(a+1,a+1+n);
for(int i=1;i<=n;i++){
while(tot>0&&a[i].w>=a[tot].w)tot--;
a[++tot]=a[i];
}
n=tot;
int t=2,h=1;
for(int i=1;i<=n;i++){
while(h+1<t&&G(q[h+1],q[h])<=S(q[h+1],q[h])*a[i].l)h++;
dp[i]=dp[q[h]]+a[i].l*a[q[h]+1].w;
while(h+1<t&&G(i,q[t-1])*S(q[t-1],q[t-2])<=G(q[t-1],q[t-2])*S(i,q[t-1]))t--;
q[t++]=i;
}
printf("%lld",dp
);
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: