P1578 奶牛浴场

题目描述

由于John建造了牛场围栏,激起了奶牛的愤怒,奶牛的产奶量急剧减少。为了讨好奶牛,John决定在牛场中建造一个大型浴场。但是John的奶牛有一个奇怪的习惯,每头奶牛都必须在牛场中的一个固定的位置产奶,而奶牛显然不能在浴场中产奶,于是,John希望所建造的浴场不覆盖这些产奶点。这回,他又要求助于Clevow了。你还能帮助Clevow吗?

John的牛场和规划的浴场都是矩形。浴场要完全位于牛场之内,并且浴场的轮廓要与牛场的轮廓平行或者重合。浴场不能覆盖任何产奶点,但是产奶点可以位于浴场的轮廓上。

Clevow当然希望浴场的面积尽可能大了,所以你的任务就是帮她计算浴场的最大面积。

输入输出格式

输入格式:

输入文件的第一行包含两个整数L和W,分别表示牛场的长和宽。文件的第二行包含一个整数n,表示产奶点的数量。以下n行每行包含两个整数x和y,表示一个产奶点的坐标。所有产奶点都位于牛场内,即:0<=x<=L,0<=y<=W。

输出格式:

输出文件仅一行,包含一个整数S,表示浴场的最大面积。

输入输出样例

输入样例#1: 复制

10 10

4

1 1

9 1

1 9

9 9

输出样例#1: 复制

80

说明

0<=n<=5000

1<=L,W<=30000

Winter Camp 2002



最大子矩形问题加上一个奇怪条件:边界可以和障碍重合

就是特判变得更加麻烦了

\(O(n*m)\)

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

int i,m,n,j,k,a[5001][5001],b[5001][5001],l[5001][5001],r[5001][5001],g,h,ans,las;

int main()
{
    scanf("%d%d%d",&n,&m,&k);
    for(i=1;i<=k;i++)
    {
        scanf("%d%d",&g,&h);
        a[g][h]=1;
    }

    for(i=1;i<=n;i++)
        for(j=0;j<=m;j++)
            if(!a[i-1][j]) b[i][j]=b[i-1][j]+1;
            else b[i][j]=1;

    for(i=1;i<=n;i++)
    {
        las=0;
        for(j=0;j<=m;j++)
        {
            if(b[i][j]>1) l[i][j]=max(l[i-1][j],las);
            else l[i][j]=0;
            if(a[i-1][j]) las=j;
        }
    }
    memset(r,0x3f,sizeof(r));
    for(i=1;i<=m;i++) a[i][m]=m;
    for(i=1;i<=n;i++)
    {
        las=m;
        for(j=m;j>=0;j--)
        {
            if(b[i][j]>1) r[i][j]=min(r[i-1][j],las);
            else r[i][j]=m;
            if(a[i-1][j]) las=j;
        }
    }

    for(i=1;i<=n;i++)
        for(j=0;j<=m;j++)
            ans=max(ans,b[i][j]*(r[i][j]-l[i][j]));
    printf("%d",ans);
}

\(O(s^2)\)

#include<iostream>
#include<stdio.h>
#include<cmath>
#include<algorithm>
using namespace std;

int i,m,n,j,k,ans;
struct vv
{
    int x,y;
} a[1000001];

bool cmp1(vv a,vv b) {return a.x<b.x;}
bool cmp2(vv a,vv b) {return a.y<b.y;}
bool cmp3(vv a,vv b) {return a.y>b.y;}

void dfs()
{
    for(int i=1;i<k;i++)
    {
        int maxx=n, minn=0;
        for(int j=i+1;j<=k;j++)
        {
            ans=max(ans,abs(a[j].y-a[i].y)*(maxx-minn));
            if(a[i].x==a[j].x) break;
            if((a[j].x<a[i].x)&&(a[j].x>minn)) minn=a[j].x;
            if((a[j].x>a[i].x)&&(a[j].x<maxx)) maxx=a[j].x;
        }
    }
}

int main()
{
    scanf("%d%d%d",&n,&m,&k);
    for(i=1;i<=k;i++) scanf("%d%d",&a[i].x,&a[i].y);
    a[++k].x=0; a[k].y=0;  a[++k].x=0; a[k].y=m;
    a[++k].x=n; a[k].y=0;  a[++k].x=n; a[k].y=m;
    sort(a+1,a+1+k,cmp1);
    for(i=2;i<=k;i++) ans=max(ans,(a[i].x-a[i-1].x)*m);
    sort(a+1,a+1+k,cmp2);  dfs();
    sort(a+1,a+1+k,cmp3);  dfs();
    printf("%d",ans);
}

原文地址:https://www.cnblogs.com/ZUTTER/p/9477446.html

时间: 2024-07-31 08:24:25

P1578 奶牛浴场的相关文章

洛谷P1578 奶牛浴场

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

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

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

Vijos1055 奶牛浴场(极大化思想求最大子矩形)

思路详见 王知昆<浅谈用极大化思想解决最大子矩形问题> 写得很详细(感谢~....) 因为不太会用递推,所以用了第一种方法,时间复杂度是O(n^2),n为枚举的点数,对付这题绰绰有余 思路也很简单 先根据x排序 之后两重循环,枚举i后的每一个点j到i可以形成的矩形面积 怎么求这个矩形面积呢? 非常简单,miny,maxy,分别表示纵坐标的上下界 如果枚举的点j比i的y大,那么就修改上界,反之,修改下界(具体的,可以看论文中的图,更直观些) 这里需要注意两个遗漏的地方(论文中也有特别提到) 就是

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

[luoguP1578] 奶牛浴场(DP)

传送门 O(s2)算法 详见论文 王知昆--浅谈用极大化思想解决最大子矩形问题 我就复制你能把我怎么样QAQ #include <cstdio> #include <iostream> #include <algorithm> #define N 5010 #define max(x, y) ((x) > (y) ? (x) : (y)) #define min(x, y) ((x) < (y) ? (x) : (y)) int L, W, n, ans;

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

题意:链接 方法:最大子矩阵之算♂法① 解析: 首先谈到最大子矩阵,我们可能会想到之前做过的盖房子?,那道DP求解的题目. 然而这种题目当然有更高♂端的算法. 比如接下来要谈到的算法①. 我们先来观察数据范围,n,m<=30000,这下就玩完了,怎么dp? 一下子就D掉了你原来的算法,真是不留情面. 那么我们来介绍一种新的算法. 首先谈暴力,枚举各种坏点,但这种的复杂度呢?甚至可能达到6次方,所以怎么优化呢? 按照经验,这种坐标图排个序就能降下复杂度什么的. 于是有神犇介绍了s^2复杂度的算法,

奶牛浴场

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

奶牛浴场,最大子矩阵

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

[DP专题]悬线法

reference:浅谈用极大化思想解决最大子矩阵问题 两种思路: 1.思想一:枚举所有的极大有效子矩形,如奶牛浴场 2.思想二:垂线法(后文介绍) 题目来源: [最大全0子正方形]p1387 最大正方形 P1169 棋盘制作 [最大全0子正方形]p2701 巨大的牛棚 [最大子矩阵的和(1e3数量级)]p4147 玉蟾宫 P1578 奶牛浴场 本题坐标范围在3e4,所以无法dp,爆内存 reference [缺陷:可拓展性不够(后文例题介绍),在点(最多N * M)密集的情况下表现较差] #d