标签:数组 reverse 递增 nes 最小 inline pair dig esc
约翰准备扩大他的农场,眼前他正在考虑购买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.
4
100 1
15 15
20 5
1 100
500
none
#include<bits/stdc++.h>
#define LL long long
LL in() {
char ch; int x = 0, f = 1;
while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
return x * f;
}
const int maxn = 50505;
using std::pair;
using std::make_pair;
pair<LL, LL> mp[maxn], a[maxn];
int cnt;
LL f[maxn];
LL X(int x) { return a[x + 1].second; }
LL Y(int x) { return f[x]; }
double K(int x, int y) { return (double)(Y(x) - Y(y)) / (double)(X(x) - X(y)); }
int main() {
int n = in();
for(int i = 1; i <= n; i++) mp[i].first = in(), mp[i].second = in();
std::sort(mp + 1, mp + n + 1);
LL max = 0;
for(int i = n; i >= 1; i--) {
if(mp[i].second > max) a[++cnt] = mp[i];
max = std::max(max, mp[i].second);
}
std::reverse(a + 1, a + cnt + 1);
static int q[maxn], head, tail;
for(int i = 1; i <= cnt; i++) {
LL k = a[i].first;
while(head < tail && k > K(q[head], q[head + 1])) head++;
f[i] = f[q[head]] - a[i].first * a[q[head] + 1].second;
while(head < tail && K(q[tail], q[tail - 1]) > K(i, q[tail - 1])) tail--;
q[++tail] = i;
}
printf("%lld\n", -f[cnt]);
return 0;
}
P2900 [USACO08MAR]土地征用Land Acquisition
标签:数组 reverse 递增 nes 最小 inline pair dig esc
原文地址:https://www.cnblogs.com/olinr/p/10227089.html