zoukankan      html  css  js  c++  java
  • 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
    ",f[len]);
        return 0;
    } 
  • 相关阅读:
    windows定时关机命令
    centos 共享文件目录
    Linux 虚拟机的安全加固建议
    使用mondorescue将本机linux centos 7服务器制作成光盘
    CentOS 7 救援模式启用网卡及重新获取IP地址
    CentOS 7修复MBR和GRUB
    使用windows性能计数器监控cpu使用率
    CodeForces-916A-jamie and Alarm Snooze(笨比题目)
    CodeForces-721D-Maxim and Array(优先队列,贪心,分类讨论)
    CodeForces-721C-Journey(DAG, DP)
  • 原文地址:https://www.cnblogs.com/Never-mind/p/7631218.html
Copyright © 2011-2022 走看看