• Vijos1055(极大子矩阵)


    题目链接

    分析:
    浅谈用极大化思想解决最大子矩阵问题
    算法二的复杂度是n*m,显然这道题是不能承受的
    那么我们只能看一下算法一了:

    算法一的代码量明显多于算法二
    主要分成两大部分:

    一.x轴上

    首先按照x坐标排序
    第一面扫描我们从左到右,
    miny表示最大向下扩展到的下边界,maxy表示最大向上扩展到的上边界,
    dx表示矩阵的长,dy表示矩阵的宽,s表示矩阵的面积
    针对每一个点,我们先向右扩展,
    初始状态是:

    miny=0;   //默认能扩展到边界
    maxy=m;
    s=0;

    需要注意的是再向右推的时候,我们要同时维护miny和maxy
    就像论文中说的那样:

    if (po[j].y<=po[i].y&&po[j].y>miny) miny=po[j].y;
    if (po[j].y>=po[i].y&&po[j].y<maxy) maxy=po[j].y;

    如图:
    这里写图片描述
    单纯这样转移完之后,我们发现有一块面积我们没有计算过:
    这里写图片描述
    所以在第一层循环中,我们需要再单独计算一下这块面积

    之后我们再从后往前,向左扩展,重复上述操作
    这里写图片描述

    二.y轴上

    进行完上述操作后,我们发现
    还有一部分面积我们没有考虑到
    这里写图片描述
    我们把点按照y排序
    那么每块的面积就是

    dx=n;
    dy=po[i].y-po[i-1].y;
    s=dx*dy;

    当然,第一个点和最后一个点需要特殊处理一下
    这里写图片描述

    这里写代码片
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    int n,m,num,maxy,miny,ans=0,dx,dy,s;
    struct node{
        int x,y;
    };
    node po[10000];
    
    int cmp1(const node &a,const node &b)
    {
        return a.x<b.x;
    }
    
    int cmp2(const node &a,const node &b)
    {
        return a.y<b.y;
    }
    
    void doit()
    {
        int i,j,k;
        sort(po+1,po+1+num,cmp1);
        for (i=1;i<=num;i++)
        {
            miny=0,maxy=m,s=0;
            for (j=i+1;j<=num;j++)
            {
                dx=po[j].x-po[i].x;
                dy=maxy-miny;
                s=dx*dy;
                ans=max(ans,s);
                if (po[j].y<=po[i].y&&po[j].y>miny) miny=po[j].y;
                if (po[j].y>=po[i].y&&po[j].y<maxy) maxy=po[j].y;
            }
            dx=n-po[i].x;
            dy=maxy-miny;
            s=dx*dy;
            ans=max(ans,s);
        }
        for (i=num;i>=1;i--)
        {
            miny=0,maxy=m,s=0;
            for (j=i-1;j>=1;j--)
            {
                dx=po[i].x-po[j].x;
                dy=maxy-miny;
                s=dx*dy;
                ans=max(ans,s);
                if (po[j].y<=po[i].y&&po[j].y>miny) miny=po[j].y;
                if (po[j].y>=po[i].y&&po[j].y<maxy) maxy=po[j].y;
            }
            dx=po[i].x;
            dy=maxy-miny;
            s=dx*dy;
            ans=max(ans,s);
        }
    
        sort(po+1,po+1+num,cmp2);
        for (i=1;i<=num;i++)
        {
            if (i==1) dy=po[i].y,s=n*dy,ans=max(ans,s);
            if (i==num) dy=m-po[i].y,s=n*dy,ans=max(ans,s);
            if (i>1)
            {
                dy=po[i].y-po[i-1].y;
                s=n*dy;
                ans=max(ans,s);
            }
        }
        printf("%d",ans);
    }
    
    int main()
    {
        scanf("%d%d%d",&n,&m,&num);
        if (num==0)
        {
            printf("%d",n*m);
            return 0;
        }
        for (int i=1;i<=num;i++)
            scanf("%d%d",&po[i].x,&po[i].y);
        doit();
        return 0;
    }
  • 相关阅读:
    搭建zabbix监控
    liunx 下ctrl+D问题解决方案
    linux配置双线策略
    Discuz! X2.5读写分离
    慢谈MYSQL常用SQL语句
    CentOS 6.5系统安装配置LAMP(Apache+PHP5+MySQL)服务器环境
    自动抓包shell脚本
    zabbix实施部署原理架构
    ftp搭建教程
    DNS搭建教程
  • 原文地址:https://www.cnblogs.com/wutongtong3117/p/7673166.html
Copyright © 2020-2023  润新知