POJ 2029--Get Many Persimmon Trees +DP

题意: 在一个w*h宽的矩形中有些位置有树有些位置没有,然后我们须要从中选一个s*t的矩形,使得里面含有的树最多.
思路: 我们将有树位置的值看成1,其他为0,然后成了选一个区域值最大.然后考虑这个问题的一维形式,在一维的情况下,我们非常easy得到一个方案:先处理前缀和,然后就能够枚举区间端点的起点,O(1)时间计算区间和,然后取当中的最大值为答案.
这道题我们能够按相同的思路来做,先求出(1,1)到(i,j)的区间和,然后枚举起点,O(1)的时间计算区间和,取当中最大值为答案.
当然这道题由于数据量较小,全然能够暴力,还能够用二维的树状数组来做.

代码例如以下:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;

#define maxn 105

int Map[maxn][maxn],dp[maxn][maxn];

int main()
{
     // freopen("in.txt","r",stdin);
      int w,h,s,t,n;
      while(scanf("%d",&n)&&n)
      {
            scanf("%d%d",&w,&h);
            memset(dp,0,sizeof(dp));
            memset(Map,0,sizeof(Map));
            for(int i=0;i<n;i++)
            {
                  int x,y;
                  scanf("%d%d",&x,&y);
                  Map[x][y]=1;
            }
            scanf("%d%d",&s,&t);
            for(int i=1;i<=w;i++)
              for(int j=1;j<=h;j++)
                   dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]+Map[i][j];
           int ans=0;
           for(int i=1;i<=w;i++)
              for(int j=1;j<=h;j++)
              {
                     int ii=i+s-1;
                     int jj=j+t-1;
                     if(ii>w||jj>h)   continue;
                     ans=max(ans,dp[ii][jj]-dp[ii][j-1]-dp[i-1][jj]+dp[i-1][j-1]);
              }
           printf("%d\n",ans);
      }
  return 0;
}
posted @ 2016-03-06 16:26  blfshiye  阅读(257)  评论(0编辑  收藏  举报