BZOJ1597(Usaco2008 Mar)[土地购买]--斜率优化DP

【链接】
bzoj1597

【题目大意】

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

【解题报告】

首先可以想到对于一些土地可能存在一些包含关系,所以先去掉被包含的土地会更好考虑些(其实做了这些步骤后r就是降序的,而c是升序的)。其实此题可以看出是线性DP,定义 f[i]=min(f[i],f[j]r[j+1]c[i])(j<i) ,但是好像n太大过不了,但因为满足以上条件,所以直接斜率优化即可。

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
const int maxn=50005;
int n,tot,MAX,hed,til,que[maxn];
LL f[maxn];
struct wjd
{
    int r,c;
    bool operator < (const wjd &a) const{
        return r>a.r;
    }
}a[maxn];
inline int Read()
{
    int res=0; char ch=getchar();
    while (ch<'0'||ch>'9') ch=getchar();
    while (ch>='0'&&ch<='9') res=res*10+ch-48,ch=getchar();
    return res;
}
int X(int i,int j) {return a[i+1].r-a[j+1].r;}
LL Y(int i,int j) {return f[j]-f[i];}
int main()
{
    freopen("1597.in","r",stdin);
    freopen("1597.out","w",stdout);
    n=Read(); tot=MAX=0;
    for (int i=1; i<=n; i++) a[i]=(wjd){Read(),Read()};
    sort(a+1,a+1+n);
    for (int i=1; i<=n; i++)
     if (a[i].c>MAX) MAX=a[i].c,a[++tot]=a[i];
    hed=til=1; que[0]=que[1]=0;
    for (int i=1; i<=tot; i++)
    {
        while (hed<til&&Y(que[hed],que[hed+1])<=(LL)a[i].c*X(que[hed],que[hed+1])) hed++;
        f[i]=f[que[hed]]+(LL)a[que[hed]+1].r*a[i].c;
        while (hed<til&&Y(que[til-1],que[til])*X(que[til],i)>=Y(que[til],i)*X(que[til-1],que[til])) til--;
        que[++til]=i;
    }
    printf("%lld\n",f[tot]);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值