# BZOJ 1597: [Usaco2008 Mar]土地购买 斜率优化

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

Time Limit: 10 Sec  Memory Limit: 162 MB

## Input

* 第1行: 一个数: N

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

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

4
100 1
15 15
20 5
1 100

500

## HINT

按照X排序， 手动删掉一些无影响的选择

剩下的都是 X增大，Y减小的矩阵

那么答案必须是选择一段连续的矩阵了

这个时候就可以DP

他是有单调性的

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cmath>
using namespace std;
#define LL long long
const int N = 1e5+10, inf = 1e9, mod = 1e9+7;
struct ss{
LL x,y;
}Q[N],tmp[N];
int cmp1(ss s1,ss s2) {
if(s1.x == s2.x) return s1.y < s2.y;
else return s1.x < s2.x;
}
int cmp2(ss s1,ss s2) {
if(s1.y == s2.y) return s1.x < s2.x;
else return s1.y < s2.y;
}
int n,q[N];
LL dp[N];
int main() {
scanf("%d",&n);
for(int i = 1; i <= n; ++i) {
scanf("%lld%lld",&Q[i].x,&Q[i].y);
}
sort(Q+1,Q+n+1,cmp1);
int cnt = 0;
for(int i = 1; i <= n; ++i) {
while(cnt && tmp[cnt].y<=Q[i].y)cnt--;
tmp[++cnt] = Q[i];
}
n = cnt;
for(int i = 1; i <= n; ++i) Q[i] = tmp[i],dp[i] = 1e15;
dp[0] = 0;
int l = 1,r = 2;q[1] = 0;
q[2] = 1;dp[1] = 1LL*Q[1].x * Q[1].y;
for(int i = 2; i <= n; ++i) {
while(l < r && dp[q[l+1]] - dp[q[l]] < 1LL*(Q[q[l]+1].y - Q[q[l+1]+1].y) * Q[i].x) ++l;
dp[i] = dp[q[l]] + 1LL*Q[i].x * Q[q[l]+1].y;
while(l < r && (dp[q[r]]-dp[q[r-1]]) * 1LL*(Q[q[r]+1].y-Q[i+1].y) > (dp[i] - dp[q[r]]) * (Q[q[r-1]+1].y-Q[q[r]+1].y)) --r;
q[++r] = i;
}
printf("%lld\n",dp[n]);
return 0;
}

posted @ 2017-10-07 14:10  meekyan  阅读(389)  评论(0编辑  收藏  举报