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 }