BZOJ 1597 [Usaco2008 Mar]土地购买 (斜率优化dp)

题意:

给你一些x*y的土地,分成一组一组购买土地,其代价为这组里的max{x}*max{y},问你全部买下最少多少钱

思路:

有一个土地为x1*y1,如果存在一个x2*y2,且x1<=x2&&y1<=y2,那么我们就不需要考虑x1*y1的土地了

这样我们可以处理出一个x单调递增,同时y单调递减的数组

显然可以看出,每一组购买的土地应该是这个数组中连续的一段

简单证明:在购买的一组土地总量不变的情况下,该组购买方案为一个单独的x1*y1再加上数组中一段连续的土地[l,r],那么max{x}=a[r].x,而max{y}=y1

此时一定存在连续的[l-1,r],其max{y}=a[l-1].y<y1,比选择x1*y1更优,所以应该选连续的一段

所以我们根据新数组,可以写出dp方程:

f[i]=min(f[j]+a[i].x*a[j+1].y)

斜率优化即可

由于a[j+1].y单调递增,我们只需要单调队列维护一个下凸壳

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
//#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map>
    
#define fst first
#define sc second
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
#define rc root<<1|1
 
using namespace std;
 
typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int       ,int> PI;
typedef pair<ll,ll> PLL;
 
const db eps = 1e-6;
const int mod = 998244353;
const int maxn = 2e6+100;
const int maxm = 2e6+100;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
//const db pi = acos(-1.0);
 
int n;
PLL a[maxn],b[maxn];
ll f[maxn];
int q[maxn];
bool cmp(PLL a, PLL b){return a.fst==b.fst?a.sc<b.sc:a.fst<b.fst;}
int main(){
    scanf("%d", &n);
    for(int i = 1; i <= n; i++){
        scanf("%lld%lld", &a[i].fst, &a[i].sc);
    }
    sort(a+1,a+1+n,cmp);
    int tot=0;
    for(int i = 1; i <= n; i++){
        while(tot&&a[i].sc>=b[tot].sc)tot--;
        b[++tot]=a[i];
    }
    int l=0,r=0;
    for(int i = 1; i <= tot; i++){
        while(l<r&&(f[q[l+1]]-f[q[l]])<=b[i].fst*(b[q[l]+1].sc-b[q[l+1]+1].sc))l++;
        int j = q[l];
        f[i]=f[j]+b[i].fst*b[j+1].sc;
        while(l<r&&(f[q[r]]-f[q[r-1]])*(b[q[r]+1].sc-b[i+1].sc)>=(f[i]-f[q[r]])*(b[q[r-1]+1].sc-b[q[r]+1].sc))r--;
        q[++r]=i;
    }
    printf("%lld",f[tot]);
    return 0;
}
/*
4
100 1
15 150
20 5
1 100
 */
原文地址:https://www.cnblogs.com/wrjlinkkkkkk/p/11312056.html