思路:
dp[i][j]表示以第i行第j列元素为矩阵右下角所能得到的最大福字的大小。
对于这一个矩阵, dp[i][j]对于dp[i][j-1]来说属于竖向扩充。
同理,dp[i][j]对于dp[i-1][j]来说属于横向扩充。
所以
if(a[i-1][j]==a[i][j]-1 && a[i][j-1]==a[i][j]-1) dp[i][j] = dp[i-1][j-1]+1;
其他条件便只能由所在一个元素去构成一个福字矩阵了,大小是1。
数据弱 AC了 但是想了想
3
1 1 1
1 2 3
1 3 4
就是错的 答案应该是2。。。
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int a[1005][1005],dp[1005][1005]; 5 6 int main(){ 7 int n; cin>>n; 8 for(int i=1; i<=n; i++) 9 for(int j=1; j<=n; j++) 10 cin >> a[i][j]; 11 for(int i=1; i<=n; i++) 12 for(int j=1; j<=n; j++) 13 dp[i][j] = 1; 14 15 int ans = 0; 16 for(int i=1; i<=n; i++) 17 for(int j=1; j<=n; j++){ 18 if(a[i-1][j]==a[i][j]-1 && a[i][j-1]==a[i][j]-1) 19 dp[i][j] = dp[i-1][j-1]+1; 20 ans = max(ans,dp[i][j]); 21 } 22 23 cout << ans << endl; 24 } 25 26 27 正解: 28 29 设 dp[i][j] 为以 i,j 位置为正方形右下角点所能构成的满足条件得到最大正方形,同时 用 up[i][j] 表示以 i,j 位置为最底部向上能连续满足条件的位置个数,用 lf[i][j] 表示以 i,j 位置为最右端向左能连续满足条件的位置个数。 30 31 转移: 32 33 if(mp[i][j] == mp[i-1][j-1]+2) 34 dp[i][j] = min(min(up[i][j],lf[i][j]), dp[i-1][j-1]+1); 35 代码: 36 37 #include <bits/stdc++.h> 38 using namespace std; 39 const int maxn = 1005; 40 41 int n; 42 int mp[maxn][maxn]; 43 int dp[maxn][maxn]; 44 int up[maxn][maxn]; 45 int lf[maxn][maxn]; 46 int main() 47 { 48 scanf("%d", &n); 49 int ans = 0; 50 for(int i=1;i<=n;i++){ 51 for(int j=1;j<=n;j++){ 52 scanf("%d", &mp[i][j]); 53 if(mp[i][j] == mp[i][j-1]+1) 54 lf[i][j] = lf[i][j-1]+1; 55 else 56 lf[i][j] = 1; 57 if(mp[i][j] == mp[i-1][j]+1) 58 up[i][j] = up[i-1][j]+1; 59 else 60 up[i][j] = 1; 61 62 63 if(mp[i][j] == mp[i-1][j-1]+2) 64 dp[i][j] = min(min(up[i][j],lf[i][j]), dp[i-1][j-1]+1); 65 else 66 dp[i][j] = 1; 67 ans = max(ans,dp[i][j]); 68 } 69 } 70 printf("%d ", ans); 71 }