极大化思想解决最大子矩形问题

题目链接:https://vijos.org/p/1055


描述

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

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

格式

输入格式

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

输出格式

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

样例1

样例输入1[复制]

10 10
4
1 1
9 1
1 9
9 9

样例输出1[复制]

80

限制

各个测试点1s

提示

0<=n<=5000
1<=L,W<=30000


思路:最优子矩形问题,王知昆的《浅谈用极大化思想解决最大子矩形问题》完全可以理解(百度)

链接:http://hi.baidu.com/mzry1992/item/030f9740e0475ef7dc0f6cba


基本都是懂思想敲代码就是,一开始没有处理好WA了一次!

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<cmath>
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define maxn 0x3f3f3f3f
using namespace std;
int lx,ly;
int n;
struct node
{
    int x,y;
}s[5001];
bool cmp(node a,node b)
{
    if(a.x==b.x)
        return a.y>b.y;
    return a.x<b.x;
}
int main()
{
    cin.sync_with_stdio(false);
    cin>>lx>>ly;
    cin>>n;
    if(n==0)
    {
        cout<<lx*ly<<endl;
        return 0;
    }
    for(int i=1;i<=n;i++)
        cin>>s[i].x>>s[i].y;
    sort(s+1,s+n+1,cmp);
    int maxy,miny,dx,dy,area,maxs=0;
    for(int i=1;i<=n;i++)
    {
        maxy=ly;
        miny=0;
        area=0;
        for(int j=i+1;j<=n;j++)
        {
            dx=s[j].x-s[i].x;
            dy=maxy-miny;
            area=dx*dy;
            if(area>maxs)
                maxs=area;
            if(s[i].y<=s[j].y && s[j].y<=maxy)
                maxy=s[j].y;
            if(s[i].y>=s[j].y && s[j].y>=miny)
                miny=s[j].y;
        }
        dx=lx-s[i].x;
        dy=maxy-miny;
        area=dx*dy;
        if(area>maxs)
            maxs=area;
    }
    for(int i=n;i>=1;i--)
    {
        maxy=ly;
        miny=0;
        area=0;
        for(int j=i-1;j>=1;j--)
        {
            dx=s[i].x-s[j].x;
            dy=maxy-miny;
            area=dx*dy;
            if(area>maxs)
                maxs=area;
            if(s[j].y>=s[i].y && s[j].y<=maxy)
                maxy=s[j].y;
            if(s[j].y<=s[i].y && s[j].y>=miny)
                miny=s[j].y;
        }
        dx=s[i].x;
        dy=maxy-miny;
        area=dx*dy;
        if(area>maxs)
            maxs=area;
    }
    cout<<maxs<<endl;
    return 0;
}




你可能感兴趣的:(极大化思想解决最大子矩形问题)