BZOJ1597: [Usaco2008 Mar]土地购买
Posted Star_Feel
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ1597: [Usaco2008 Mar]土地购买相关的知识,希望对你有一定的参考价值。
【传送门:BZOJ1597】
简要题意:
给出n块土地,给出每块土地的长和宽,可以将n块土地分成若干组,每一组的费用是组中的长最大的土地的长与宽最大的土地的宽的乘积,求出将n块分成若干组的最小费用
题解:
首先我们将一些土地排除,排除哪些土地呢?
先将土地按长度递增排序,然后长度相同按宽度递增排序
然后排除一些长与宽都能被任意土地包含的土地,把这些土地去掉,并不影响答案
首先想到DP,f[i]表示将i块土地分组后的最小值,因为我们排序了,而且排除了一些重合的情况后,得到的土地排序肯定是长度递增而且宽度递减的,所以很容易得到DP方程f[i]=min(f[j]+s[i].x*s[j+1].y),s结构体记录土地的长和宽(x为长,y为宽),但是时间复杂度O(n2),会超时
那么就用斜率优化来优化
参考代码:
#include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<cmath> using namespace std; typedef long long LL; struct node { LL x,y; }a[51000],s[51000]; int cmp(const void *xx,const void *yy) { node n1=*(node *)xx; node n2=*(node *)yy; if(n1.x<n2.x) return -1; if(n1.x>n2.x) return 1; if(n1.y<n2.y) return -1; if(n1.y>n2.y) return 1; return 0; } /* f[i]=min(f[j]+s[i].x*s[j+1].y) j1<j2<i f[j2]+s[i].x*s[j2+1].y<=f[j1]+s[i].x*s[j1+1].y (f[j2]-f[j1])/(s[j1+1].y-s[j2+1].y)<=s[i].x */ LL f[51000]; double slop(int j1,int j2) { return (f[j2]-f[j1])/(s[j1+1].y-s[j2+1].y); } int list[51000]; int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lld%lld",&a[i].x,&a[i].y); qsort(a+1,n,sizeof(node),cmp); int len=0; s[1]=a[1];len=1; for(int i=2;i<=n;i++) { while(len>0&&a[i].y>=s[len].y) len--; s[++len]=a[i]; } memset(f,0,sizeof(f)); int head=1,tail=1;list[1]=0; for(int i=1;i<=len;i++) { while(head<tail&&slop(list[head],list[head+1])<=double(s[i].x)) head++; int j=list[head]; f[i]=f[j]+s[i].x*s[j+1].y; while(head<tail&&slop(list[tail-1],list[tail])>slop(list[tail],i)) tail--; list[++tail]=i; } printf("%lld\n",f[len]); return 0; }
以上是关于BZOJ1597: [Usaco2008 Mar]土地购买的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ 1597: [Usaco2008 Mar]土地购买
BZOJ 1597: [Usaco2008 Mar]土地购买 斜率优化
BZOJ 1597: [Usaco2008 Mar]土地购买斜率优化+凸包维护