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

## 1597: [Usaco2008 Mar]土地购买

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

## Description

= 1,000,000; 1 <= 长 <= 1,000,000). 每块土地的价格是它的面积,但FJ可以同时购买多快土地. 这些土地的价

## Input

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

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

4
100 1
15 15
20 5
1 100

500
FJ分3组买这些土地:

## Source

Gold

b为宽 a为长
dp[i]=dp[j]+(a[i]*b[j+1])

dp[j]+a[i]*b[j+1]<=dp[k]+a[i]*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.

posted @ 2017-12-26 20:38  _wsy  阅读(123)  评论(0编辑  收藏  举报