【斜率优化】BZOJ1597(Usaco2008 Mar)[土地购买]题解

来源:互联网 发布:阿里云邮箱手机验证 编辑:程序博客网 时间:2024/05/18 08:41

题目概述

n 块土地,每块土地有长 r 和宽 c ,一次可以购买若干块土地,每次购买土地的代价是选择的土地的最大 r × 最大 c ,求买下所有土地的最小代价。

解题报告

由于要买下所有土地,所以如果对于 i ,存在 j(ji) 使得 rjri,cjci ,则 i 就不需要考虑了。这样的话我们可以排序然后去掉不满足的土地,最终会剩下递减的 r 和递增的 c

然后就会发现这是线性DP, f[i]=min{f[j]+r[j+1]×c[i]|j<i} ,用斜率优化即可。

示例程序

#include<cstdio>#include<algorithm>#define fr first#define sc secondusing namespace std;typedef long long LL;const int maxn=50000;int n;pair<int,int> a[maxn+5];int Head,Tail,que[maxn+5];LL f[maxn+5];inline bool cmp(pair<int,int> a,pair<int,int> b) {return a>b;}inline LL X(int i,int j) {return a[i+1].fr-a[j+1].fr;}inline LL Y(int i,int j) {return f[j]-f[i];}int main(){    freopen("program.in","r",stdin);    freopen("program.out","w",stdout);    scanf("%d",&n);for (int i=1;i<=n;i++) scanf("%d%d",&a[i].fr,&a[i].sc);sort(a+1,a+1+n,cmp);    int Tot=n;n=0;for (int i=1,MAX=0;i<=Tot;i++) if (a[i].sc>MAX) a[++n]=a[i],MAX=a[i].sc;    f[0]=0;Head=1;que[Tail=1]=0;    for (int i=1;i<=n;i++)    {        while (Head<Tail&&Y(que[Head],que[Head+1])<=X(que[Head],que[Head+1])*a[i].sc) Head++;        f[i]=f[que[Head]]+(LL)a[que[Head]+1].fr*a[i].sc;        while (Head<Tail&&Y(que[Tail-1],que[Tail])*X(que[Tail],i)>=Y(que[Tail],i)*X(que[Tail-1],que[Tail])) Tail--;        que[++Tail]=i;    }    printf("%lld\n",f[n]);    return 0;}
阅读全文
0 0
原创粉丝点击