USACO Section 5.3 Big Barn - DP...


     看到这题就想到了USACO3.3 的 home on the range....但这题的数据量更大...用之前的方法显然效率不能满足了...之前用的是优化BFS...这里用的是DP...

     思路也很简单...DP的目的无非是要利用前面的结果来直接推出后面的结果而减少甚至排出重复计算与判断...这里用M [ i ] [ j ] 表示 ( i,j ) 点为正方形右下方的点时能得到的最大正方形(   ( i,j ) 这个点不是障碍 )...那么M [ i ] [ j ]的值实际上就是 M [ i-1 ][ j-1 ]    M [ i-1 ][ j ]     M [ i ][ j-1 ] 三个中的最小值+1...试想一下.. 点 ( i-1,j-1 )可得到对 ( i , j ) 左上角这个一块的判断情况...而 M [ i-1 ] [ j ] 能得到对当前点 ( i,j ) 上右一条的判断结果..M [ i ] [ j-1] ] 得到当前点 ( i,j ) 左下一条的判断结果...综合取交集就是 M [ i ][ j ] 能得到的最到正方形边长..

     所以如此..从左上角的点顺序判断更新到右下角的点..最复杂的数据也只需要10^6次循环...可以承受...


Program:

/*  
ID: zzyzzy12   
LANG: C++   
TASK: bigbrn
*/      
#include<iostream>      
#include<istream>  
#include<stdio.h>     
#include<string.h>      
#include<math.h>      
#include<stack>
#include<map>
#include<algorithm>      
#include<queue>   
#define oo 2000000005  
#define ll long long  
#define pi (atan(2)+atan(0.5))*2 
using namespace std;
int m,n,arc[1006][1006]; 
int ans,M[1006][1006];
int main()  
{  
      freopen("bigbrn.in","r",stdin);   
      freopen("bigbrn.out","w",stdout);
      int i,j;
      memset(arc,0,sizeof(arc));
      memset(M,0,sizeof(M));
      scanf("%d%d",&n,&m); 
      while (m--)
      {
            scanf("%d%d",&i,&j);
            arc[i][j]=1;
      } 
      ans=0;
      for (i=1;i<=n;i++)
         for (j=1;j<=n;j++)
            if (!arc[i][j])  
            {
                  M[i][j]=min(M[i-1][j-1],min(M[i][j-1],M[i-1][j]))+1;
                  if (M[i][j]>ans) ans=M[i][j];
            }       
      printf("%d\n",ans);
      return 0;     
}   


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值