luogu1578 奶牛浴场 枚举点最大子矩阵

建议看看王知昆dalao的论文,讲得很好

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int l, w, n, ans=0, sh, xi, ma;
struct Node{
	int x, y;
}nd[5105];
bool cmp1(Node u, Node v){
	return u.y<v.y;
}
bool cmp2(Node u, Node v){
	if(u.x==v.x)	return u.y<v.y;
	return u.x<v.x;
}
int main(){
	cin>>l>>w>>n;
	for(int i=1; i<=n; i++)
		scanf("%d %d", &nd[i].x, &nd[i].y);
	nd[++n] = (Node){0, 0};
	nd[++n] = (Node){l, 0};
	nd[++n] = (Node){0, w};
	nd[++n] = (Node){l, w};
	sort(nd+1, nd+1+n, cmp1);
	for(int i=1; i<n; i++)
		ans = max(ans, (nd[i+1].y-nd[i].y)*l);
	sort(nd+1, nd+1+n, cmp2);
	for(int i=1; i<=n; i++){
		sh = w; xi = 0; ma = l - nd[i].x;
		for(int j=i+1; j<=n; j++)
			if(nd[j].y<=sh && nd[j].y>=xi){
				if(ma*(sh-xi)<=ans)	break;
				ans = max(ans, (nd[j].x-nd[i].x)*(sh-xi));
				if(nd[j].y==nd[i].y)	break;
				else if(nd[j].y>nd[i].y)	sh = nd[j].y;
				else	xi = nd[j].y;
			}
		sh = w; xi = 0; ma = nd[i].x;
		for(int j=i-1; j>=1; j--){
			if(nd[j].y<=sh && nd[j].y>=xi){
				if(ma*(sh-xi)<=ans)	break;
				ans = max(ans, (nd[i].x-nd[j].x)*(sh-xi));
				if(nd[j].y==nd[i].y)	break;
				else if(nd[j].y>nd[i].y)	sh = nd[j].y;
				else	xi = nd[j].y;
			}
		}
	}
	cout<<ans<<endl;
	return 0;
}
原文地址:https://www.cnblogs.com/poorpool/p/8031732.html