Vijos 1055 奶牛浴场 最大子矩阵 算♂法①

题意:链接

方法:最大子矩阵之算♂法①

解析:

首先谈到最大子矩阵,我们可能会想到之前做过的盖房子?,那道DP求解的题目。

然而这种题目当然有更高♂端的算法。

比如接下来要谈到的算法①。

我们先来观察数据范围,n,m<=30000,这下就玩完了,怎么dp?

一下子就D掉了你原来的算法,真是不留情面。

那么我们来介绍一种新的算法。

首先谈暴力,枚举各种坏点,但这种的复杂度呢?甚至可能达到6次方,所以怎么优化呢?

按照经验,这种坐标图排个序就能降下复杂度什么的。

于是有神犇介绍了s^2复杂度的算法,其中s为坏点数目。

首先呢,我们先将所有的坏点按照x第一关键字,y第二关键字排序,之后呢,我们枚举基准坏点,也就是作为在左边界上的坏点。假设初始的上边界为最高行,下边界为最低行。之后再扫描在其右面的所有坏点。

每扫到一个点,我们就知道二者的横坐标差距乘以上下边界差距就是目前的一个极大子矩阵的面积。

更新完答案后,还需要对上下边界进行更新,对于本题(即坏点可存在于边界处),当坏点在枚举的点的上方(含在同一行)的时候,如果坏点比当前的上边界要低,则需要更新上边界,要保证在该坏点之后枚举到的极大子矩阵不会包含该坏点。

下边界的讨论同理。

在每一次枚举的最后不要忘了更新一次包含边界的情况。

当然,我们发现,如果从右向左枚举的时候,是不会有包含左边界的情况的(某点在左边界除外),所以为了不遗漏情况,我们还需要从右向左枚举一次。

这样就结束了吗?

并没有。

左右边界都包含的情况并没有枚举到。

所以需要特殊处理一下左右边界都包含的情况,这里我采用的是重新按照y排序处理的。

然后就水过了~

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 5010
using namespace std;
int l,w,n;
struct node
{
    int x,y;
}pt[N];
int cmp(node a,node b)
{
    if(a.x==b.x)return a.y<b.y;
    return a.x<b.x;
}
int cmp2(node a,node b)
{
    if(a.y==b.y)return a.x<b.x;
    return a.y>b.y;
}
int main()
{
    scanf("%d%d%d",&l,&w,&n);
    if(!n){printf("%d\n",l*w);return 0;}
    for(int i=1;i<=n;i++)scanf("%d%d",&pt[i].x,&pt[i].y);
    sort(pt+1,pt+n+1,cmp);
    int ans=-1;
    for(int i=1;i<=n;i++)
    {
        int u=w,d=0;
        for(int j=i+1;j<=n;j++)
        {
            ans=max(ans,(pt[j].x-pt[i].x)*(u-d));
            if(pt[j].y>=pt[i].y)u=min(u,pt[j].y);
            if(pt[j].y<=pt[i].y)d=max(d,pt[j].y);
        }
        ans=max(ans,(l-pt[i].x)*(u-d));
    }
    for(int i=n;i>=1;i--)
    {
        int u=w,d=0;
        for(int j=i-1;j>=1;j--)
        {
            ans=max(ans,(pt[i].x-pt[j].x)*(u-d));
            if(pt[j].y>=pt[i].y)u=min(u,pt[j].y);
            if(pt[j].y<=pt[i].y)d=max(d,pt[j].y);
        }
        ans=max(ans,pt[i].x*(u-d));
    }
    sort(pt+1,pt+n+1,cmp2);
    for(int i=1;i<n;i++)
    {
        ans=max(ans,(pt[i].y-pt[i+1].y)*l);
    }
    ans=max(ans,(w-pt[1].y)*l);
    ans=max(ans,pt[n].y*l);
    printf("%d\n",ans);
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-09 00:30:27

Vijos 1055 奶牛浴场 最大子矩阵 算♂法①的相关文章

Vijos 1055 奶牛浴场

Description 求一个不覆盖指定点的最大子矩阵,\(n,m \leqslant 3\times 10^5,S \leqslant 5\times 10^3\) . Sol 没有名字的算法都叫xjblg算法? 枚举每个点成为极大子矩阵边界的情况,然后维护上下边界. 还有一种情况就是左右边界是矩阵两边的情况,需要预处理一下. 时间复杂度 \(O(S^2)\) 空间复杂度 \(O(S)\) Code #include<cstdio> #include<utility> #incl

BZOJ 3039 玉蟾宫 最大子矩阵 算♂法②

题意:链接 方法:最大子矩阵之算♂法② 解析: 首先这道题单调栈DP是肯定能过的,但是一点都不高端! 什么年代了还用这种方式! 所以如何彰显自己是个高端的人呢? 悬线法能满足你的需求! 什么是悬线法? 首先对于悬线的定义,对于一个n*m的坐标图中的任意一点,其向上能延伸的一个线段(不碰到坏点)称为悬线. 如果定义h[i,j]代表(i,j)该点的悬线长度. 那么,如果其上方的点是坏点,则悬线长度为0,该点为坏点,悬线长度为0,否则的话,为上方的点的悬线长度加1. 如果这么统计的话,那么最终的悬线长

vijos p1005 奶牛浴场[ 极大化思想]

奶牛浴场 描述 由于John建造了牛场围栏,激起了奶牛的愤怒,奶牛的产奶量急剧减少.为了讨好奶牛,John决定在牛场中建造一个大型浴场.但是John的奶牛有一个奇怪的习惯,每头奶牛都必须在牛场中的一个固定的位置产奶,而奶牛显然不能在浴场中产奶,于是,John希望所建造的浴场不覆盖这些产奶点.这回,他又要求助于Clevow了.你还能帮助Clevow吗? John的牛场和规划的浴场都是矩形.浴场要完全位于牛场之内,并且浴场的轮廓要与牛场的轮廓平行或者重合.浴场不能覆盖任何产奶点,但是产奶点可以位于浴

Vijos 1255 月饼盒 最大子矩阵

题意:链接 方法:最大子矩阵 解析: 做过了那么多最大子矩阵,这道题随便YY就出来了,但我有个想法啊,如果某个n*m的矩阵,有部分坏点,非坏点有权值,可正可负,则选出的无坏点子矩阵的最大和为多少? 貌似dp?不知道啊.. 先说这道题,因为坏点权值为0,可以预处理出sum[i,j]代表i,j为右下角,(1,1)为左上角的矩阵的权值和. 当然我们可以暴力枚举矩阵,不过这是4次方的过不了. 再观察发现n,m<=1000,所以我们可以选用算♂法②来搞这道题. 先预处理sum,以及le,ri,h. 然后枚

洛谷P1578 奶牛浴场

P1578 奶牛浴场 题目描述 由于John建造了牛场围栏,激起了奶牛的愤怒,奶牛的产奶量急剧减少.为了讨好奶牛,John决定在牛场中建造一个大型浴场.但是John的奶牛有一个奇怪的习惯,每头奶牛都必须在牛场中的一个固定的位置产奶,而奶牛显然不能在浴场中产奶,于是,John希望所建造的浴场不覆盖这些产奶点.这回,他又要求助于Clevow了.你还能帮助Clevow吗? John的牛场和规划的浴场都是矩形.浴场要完全位于牛场之内,并且浴场的轮廓要与牛场的轮廓平行或者重合.浴场不能覆盖任何产奶点,但是

随 机 数 算 法

一.随机数概述 在password技术中,随机序列是非常重要的,比方密钥产生.数字签名.身份认证和众多的password学协议等都要用到随机序列.所以产生高质量的随机数序列对信息的安全性具有十分关键的数据.随机数分为真随机数和伪随机数,计算机通过算法产生的随机数并不上真正意义上的随机数,非常easy被破解,仅仅能称为伪随机数.若要产生真正的随机数,必须通过硬件来实现,比方使用离子辐射事件的脉冲检測器.气体放电管和带泄露的电容等,可是为每台计算机配备这种装置上不可能.所以在此我们通过改进我们的算法

奶牛浴场,最大子矩阵

这题的正确做法是最大子矩阵,模板题 先介绍一下最大子矩阵的做法 这篇题解是蒟蒻把王知昆大佬的<浅谈极大化思想解决最大子矩阵>整理出来的 wzk大佬论文最重要的两个定义 有效子矩形:内部不包含障碍点的子矩形 极大有效子矩形:即是一个有效子矩形,切不能在找到一个包含他的有效子矩形 原文地址:https://www.cnblogs.com/xzx-1228/p/11765500.html

P1578 奶牛浴场

题目描述 由于John建造了牛场围栏,激起了奶牛的愤怒,奶牛的产奶量急剧减少.为了讨好奶牛,John决定在牛场中建造一个大型浴场.但是John的奶牛有一个奇怪的习惯,每头奶牛都必须在牛场中的一个固定的位置产奶,而奶牛显然不能在浴场中产奶,于是,John希望所建造的浴场不覆盖这些产奶点.这回,他又要求助于Clevow了.你还能帮助Clevow吗? John的牛场和规划的浴场都是矩形.浴场要完全位于牛场之内,并且浴场的轮廓要与牛场的轮廓平行或者重合.浴场不能覆盖任何产奶点,但是产奶点可以位于浴场的轮

奶牛浴场

这道题我用了扫描法,悬线法还没有填坑 首先想到尽量减少枚举量,也就是尽量让每个矩形都是有意义的,那么只有障碍点边缘有价值,所以只需要从左到右扫描一遍,得到的全部都是有意义的. 那么这种方法是否还有遗漏呢? 答案是肯定的 因为我们从左到右搜,肯定是以左边为准线,那么如果一直延伸到右边,那么如果是右边延伸到左边就会遗漏,同理,如果与左边界和右边界重合的矩形也会遗漏. 所以加入两个特判 1.从右边扫一遍,特判第一种情况 2.从上到下排序,相邻的两个点*横轴就是第二种情况 详细见代码 #include<