1. 程式人生 > >P2900 [USACO08MAR]土地征用Land Acquisition(斜率優化)

P2900 [USACO08MAR]土地征用Land Acquisition(斜率優化)

lines tag rect ive term per -- avi ted

題目描述

Farmer John is considering buying more land for the farm and has his eye on N (1 <= N <= 50,000) additional rectangular plots, each with integer dimensions (1 <= width_i <= 1,000,000; 1 <= length_i <= 1,000,000).

If FJ wants to buy a single piece of land, the cost is $1/square unit, but savings are available for large purchases. He can buy any number of plots of land for a price in dollars that is the width of the widest plot times the length of the longest plot. Of course, land plots cannot be rotated, i.e., if Farmer John buys a 3x5 plot and a 5x3 plot in a group, he will pay 5x5=25.

FJ wants to grow his farm as much as possible and desires all the plots of land. Being both clever and frugal, it dawns on him that he can purchase the land in successive groups, cleverly minimizing the total cost by grouping various plots that have advantageous width or length values.

Given the number of plots for sale and the dimensions of each, determine the minimum amount for which Farmer John can purchase all

約翰準備擴大他的農場,眼前他正在考慮購買N塊長方形的土地。如果約翰單買一塊土 地,價格就是土地的面積。但他可以選擇並購一組土地,並購的價格為這些土地中最大的長 乘以最大的寬。比如約翰並購一塊3 × 5和一塊5 × 3的土地,他只需要支付5 × 5 = 25元, 比單買合算。 約翰希望買下所有的土地。他發現,將這些土地分成不同的小組來並購可以節省經費。 給定每份土地的尺寸,請你幫助他計算購買所有土地所需的最小費用。

輸入輸出格式

輸入格式:

* Line 1: A single integer: N

* Lines 2..N+1: Line i+1 describes plot i with two space-separated integers: width_i and length_i

輸出格式:

* Line 1: The minimum amount necessary to buy all the plots.

輸入輸出樣例

輸入樣例#1: 復制
4 
100 1 
15 15 
20 5 
1 100 
輸出樣例#1: 復制
500 

說明

There are four plots for sale with dimensions as shown.

The first group contains a 100x1 plot and costs 100. The next group contains a 1x100 plot and costs 100. The last group contains both the 20x5 plot and the 15x15 plot and costs 300. The total cost is 500, which is minimal.






首先按高度遞減,否則寬度遞增來排序,這樣可以去掉被某一個陣地包含的無用陣地

這樣處理完之後,可以發現剩下的陣地有一個特點,就是高度遞減,寬度遞增,

於是不難想象,最有的方法是選連續的陣地,所以dp方程很好寫:

技術分享圖片

然後這題的斜率項是一個正數,貌似圖跟一般的不一樣啊。。。

但是靠j優於k的式子搞就完事了





 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int N=100010;
 5 inline ll read();
 6 inline void write(ll x);
 7 inline void writeln(ll x);
 8 
 9 int n,cnt=0;
10 int q[N],head=1,tail=0;
11 ll dp[N];
12 struct aa{
13     ll x,y;
14 } field[N],work[N];
15 inline bool operator<(const aa &a,const aa &b)
16 {
17     if(a.x!=b.x) return a.x<b.x;
18     return a.y<b.y;
19 }
20 #define Y(i) (dp[(i)])
21 #define X(i) (-work[(i)+1].y)
22 #define Slope(i,j) 1.0*(Y(i)-Y(j))/(X(i)-X(j))
23 #define calc(i,j) (dp[(j)]+work[i].x*work[j+1].y)
24 
25 inline ll read()
26 {
27     ll s=0;
28     bool flag=false;
29     char ch=getchar();
30     for(;ch<0||ch>9;ch=getchar()) if(ch==-) flag=true;
31     for(;0<=ch&&ch<=9;ch=getchar()) s=(s<<3)+(s<<1)+(ch^48);
32     if(flag) return -s;
33     return s;
34 }
35 inline void write(ll x)
36 {
37     if(!x)
38     {
39         putchar(0),putchar( );
40         return ;
41     }
42     if(x<0) putchar(-),x=-x;
43     char ch[20];
44     int tot=0;
45     while(x) ch[++tot]=x%10,x/=10;
46     for(int i=tot;i;i--) putchar(ch[i]^48);
47     putchar( );
48 }
49 inline void writeln(ll x)
50 {
51     write(x);
52     putchar(\n);
53 }
54 
55 int main()
56 {
57     n=read();
58     for(int i=1;i<=n;i++) field[i].x=read(),field[i].y=read();
59     sort(field+1,field+n+1);
60     for(int i=1;i<=n;i++)
61     {
62         while(cnt&&field[i].y>=work[cnt].y) cnt--;
63         work[++cnt]=field[i];
64     }
65     n=cnt;
66     memset(dp,0x3f,sizeof(dp));
67     dp[0]=0;
68     q[++tail]=0;
69     for(int i=1;i<=n;i++)
70     {
71         for(;head<tail&&Slope(q[head],q[head+1])<=work[i].x;head++);
72         dp[i]=calc(i,q[head]);
73         for(;head<tail&&Slope(q[tail-1],q[tail])>=Slope(q[tail],i);tail--);
74         q[++tail]=i;
75     }
76     writeln(dp[n]);
77     return 0;
78 }

P2900 [USACO08MAR]土地征用Land Acquisition(斜率優化)