题目链接:
POJ 2029 Get Many Persimmon Trees
题意:
给一个width*height的方格,然后有n个点x[i]和y[i]表示在对应的方格位置上有一个点,问在方格中画一个row*col的矩形最多能圈住多少点?数据范围:width、height<=100,n<=500.
分析:
用二维树状数组存点的数量,然后遍历每一个点就好了。二维dp也能做。
//388k 16MS
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAX_N=110;
int n,width,hei,row,col;
int bits[MAX_N][MAX_N];
struct Point{
int x,y;
}point[MAX_N*5];
inline void update(int a,int b)
{
for(int i=a;i<MAX_N;i+=(i&(-i))){
for(int j=b;j<MAX_N;j+=(j&(-j))){
bits[i][j]++;
}
}
}
inline int sum(int a,int b)
{
int res=0;
for(int i=a;i>0;i-=(i&(-i))){
for(int j=b;j>0;j-=(j&(-j))){
res+=bits[i][j];
}
}
return res;
}
int main()
{
//freopen("poj2029in.txt","r",stdin);
while(~scanf("%d",&n)&&n){
memset(bits,0,sizeof(bits));
scanf("%d%d",&width,&hei);
width++,hei++;
for(int i=0;i<n;i++){
int a,b;
scanf("%d%d",&a,&b);
a++,b++;
point[i].x=a,point[i].y=b;
update(a,b);
}
scanf("%d%d",&row,&col);
int ans=0;
for(int i=2;i+row-1<=width;i++){
for(int j=2;j+col-1<=hei;j++){
int tmp=sum(i+row-1,j+col-1)+sum(i-1,j-1)-sum(i-1,j+col-1)-sum(i+row-1,j-1);
//printf("i=%d tmp=%d\n",i,tmp);
ans=max(ans,tmp);
}
}
printf("%d\n",ans);
}
return 0;
}