USACO 5.3 Big Barn (DP)

2015-03-31 23:55:36

思路:貌似和前面几章的某一题重了?

  dp[i][j] 表示以(i,j)这个点为左上角能构成的最大正方形的边长。

  挺巧妙的转移方程:dp[i][j] = min(dp[i + 1][j + 1],min(dp[i + 1][j],dp[i][j + 1])) + 1

  这样需要倒推... 想正推换一种dp定义即可。

 1 /*
 2 ID:naturec1
 3 PROG: bigbrn
 4 LANG: C++
 5 */
 6 #include <cstdio>
 7 #include <cstring>
 8 #include <cstdlib>
 9 #include <cmath>
10 #include <vector>
11 #include <map>
12 #include <set>
13 #include <stack>
14 #include <queue>
15 #include <string>
16 #include <iostream>
17 #include <algorithm>
18 using namespace std;
19 
20 #define MEM(a,b) memset(a,b,sizeof(a))
21 #define REP(i,n) for(int i=0;i<(n);++i)
22 #define FOR(i,a,b) for(int i=(a);i<=(b);++i)
23 #define getmid(l,r) ((l) + ((r) - (l)) / 2)
24 #define MP(a,b) make_pair(a,b)
25 
26 typedef long long ll;
27 typedef pair<int,int> pii;
28 const int INF = (1 << 30) - 1;
29 
30 int N,T;
31 bool g[1010][1010];
32 int dp[1010][1010];
33 
34 int main(){
35     freopen("bigbrn.in","r",stdin);
36     freopen("bigbrn.out","w",stdout);
37     int a,b;
38     scanf("%d%d",&N,&T);
39     REP(i,T){
40         scanf("%d%d",&a,&b);
41         g[a][b] = 1;
42     }
43     dp[N][N] = !g[a][b];
44     int ans = 0;
45     for(int i = N; i >= 1; --i){
46         for(int j = N; j >= 1; --j) if(!g[i][j]){
47             dp[i][j] = min(dp[i + 1][j + 1],min(dp[i + 1][j],dp[i][j + 1])) + 1;
48             ans = max(ans,dp[i][j]);
49         }
50     }
51     printf("%d\n",ans);
52     return 0;
53 }

 

posted @ 2015-03-31 23:59  Naturain  阅读(134)  评论(0编辑  收藏  举报