hiho1469 - 简单dp
题目大意:
从一个大正方形数组里面找一个小正方形,满足其中的每个位置上的数都恰好比他的左边的那个和上边的那个大1(如果左边或上边的那个不存在的话就无此要求)。
比如
1 2 3
2 3 4
3 4 5
----------------------------------------------------------------------------------------
维护满足条件的以i,j为右下顶点的最大矩形的两个边长,j方向延长为dp[i][j][0],i方向为dp[i][j][1];
#include <set> #include <map> #include <stack> #include <queue> #include <cmath> #include <vector> #include <string> #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #define MAX(a,b) ((a)>=(b)?(a):(b)) #define MIN(a,b) ((a)<=(b)?(a):(b)) #define OO 0x0fffffff using namespace std; const int N = 1024; int data[N][N]; int dp[N][N][2]; int main(){ int n; cin>>n; for(int i=0;i<n;i++) for(int j=0;j<n;j++){ cin>>data[i][j]; dp[i][j][0] = dp[i][j][1] = 1; } bool flagi,flagj; for(int i=0;i<n;i++) for(int j=0;j<n;j++){ if(!(i+j)) continue; flagi = flagj = false; if(i){ if(data[i-1][j]+1==data[i][j]){ dp[i][j][1]=dp[i-1][j][1]+1; flagi = true; } } if(j){ if(data[i][j-1]+1==data[i][j]){ dp[i][j][0]=dp[i][j-1][0]+1; flagj = true; } } if(flagi&&flagj){ dp[i][j][1]=MIN(dp[i][j][1],dp[i][j-1][1]); dp[i][j][0]=MIN(dp[i][j][0],dp[i-1][j][0]); } } int ans = 1; for(int i=0;i<n;i++) for(int j=0;j<n;j++){ ans = MAX(ans,MIN(dp[i][j][0],dp[i][j][1])); } printf("%d\n",ans); return 0; }