bzoj1597[Usaco2008 Mar]土地购买 斜率优化dp
1597: [Usaco2008 Mar]土地购买
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 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块土地.
100 1
15 15
20 5
1 100
输入解释:
共有4块土地.
Sample Output
500
FJ分3组买这些土地:
第一组:100x1,
第二组1x100,
第三组20x5 和 15x15 plot.
每组的价格分别为100,100,300, 总共500.
FJ分3组买这些土地:
第一组:100x1,
第二组1x100,
第三组20x5 和 15x15 plot.
每组的价格分别为100,100,300, 总共500.
HINT
Source
按长从小到大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]
1 #include<cstdio> 2 #include<algorithm> 3 #include<queue> 4 #define ll long long 5 #define N 500005 6 using namespace std; 7 ll dp[N];int q[N]; 8 struct square{ll l,w;bool operator <(const square &b)const{return l==b.l?w<b.w:l<b.l;}}a[N]; 9 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;} 10 int main(){ 11 int n; 12 scanf("%d",&n); 13 for(int i=1;i<=n;i++)scanf("%d%d",&a[i].l,&a[i].w); 14 int tot=0;sort(a+1,a+1+n); 15 for(int i=1;i<=n;i++){ 16 while(tot>0&&a[i].w>=a[tot].w)tot--; 17 a[++tot]=a[i]; 18 } 19 n=tot; 20 int t=2,h=1; 21 for(int i=1;i<=n;i++){ 22 while(h+1<t&&G(q[h+1],q[h])<=S(q[h+1],q[h])*a[i].l)h++; 23 dp[i]=dp[q[h]]+a[i].l*a[q[h]+1].w; 24 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--; 25 q[t++]=i; 26 } 27 printf("%lld",dp[n]); 28 return 0; 29 }
If you live in the echo,
your heart never beats as loud.
如果你生活在回声里,
你的心跳声永远不会轰鸣作响。