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;
}
拙いものと思えども、
その手に握る其れこそが、
いつか幻想を生んでいく。