障碍点最大子矩阵

题目链接:https://www.luogu.org/problemnew/show/P1578

障碍点个数S

最坏时间复杂度O(S^2) ,实际运行中因为剪枝优化会快很多。

障碍点可以在边界上。

#include <bits/stdc++.h>
#define ll long long
#define mp make_pair
#define pb push_back
#define sec second
#define fir first
#define rep(i,a,b) for(int i = (a); i <= (b); i++)
#define per(i,a,b) for(int i = (a); i >= (b); i--)
#define all(x) (x).begin(), (x).end()
#define SZ(x) ((int)(x).size())
#define pii pair<int,int>
using namespace std;
vector<pii> s;
int maxx = 0;
bool cmp(pii x, pii y) {
    return x.sec<y.sec;
}
int main() {
    //freopen("a.txt","r",stdin);
    ios::sync_with_stdio(0);
    int n, m, k;
    cin>>n>>m>>k;
    rep(i, 1, k) {
        int x, y;
        cin>>x>>y;
        s.pb(mp(x,y));
    }
    s.pb(mp(0,0));                                  //将四个角设置为障碍点
    s.pb(mp(n,m));
    s.pb(mp(0,m));
    s.pb(mp(n,0));
    sort(all(s),cmp);
    rep(i, 0, SZ(s)-2) 
        maxx = max(maxx,n*(s[i+1].sec-s[i].sec));   //特判左右边界均无障碍点
    sort(all(s));
    s.erase(unique(all(s)),s.end());
    rep(i, 0, SZ(s)-1) {                            //枚举左边界障碍点
        int up=m,down=0,t=n-s[i].fir;
        rep(j, i+1, SZ(s)-1) {
            maxx = max(maxx,(up-down)*(s[j].fir-s[i].fir));
            if(t*(up-down)<=maxx) break;            //最优化剪枝
            if(s[j].sec==s[i].sec) break;           
            if(s[j].sec>s[i].sec) up = min(up,s[j].sec);
            else down = max(down,s[j].sec);
        }
    }
    per(i, SZ(s)-1, 0) {                            //枚举右边界障碍点
        int up=m,down=0,t=s[i].fir;
        per(j, i-1, 0) {
            maxx = max(maxx,(up-down)*(s[i].fir-s[j].fir));
            if(t*(up-down)<=maxx) break;            //最优化剪枝
            if(s[j].sec==s[i].sec) break;           
            if(s[j].sec>s[i].sec) up = min(up,s[j].sec);
            else down = max(down,s[j].sec);
        }
    }
    cout<<maxx;
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值