hiho #1469 : 福字(dp)

#1469 : 福字

时间限制:6000ms
单点时限:1000ms
内存限制:256MB

描述

新年到了,你收到了一副画。你想找到里面最大的福字。

一副画是一个n × n的矩阵,其中每个位置都是一个非负整数。

一个福字被定义成是大小为 k 的正方形,满足其中的每个位置上的数都恰好比他的左边的那个和上边的那个大1(如果左边或上边的那个不存在的话就无此要求)。

比如

1 2 3
2 3 4
3 4 5

就是一个福字。(注意左上角可以是任何非负整数)。

你想找到这个矩阵中最大的福字的大小。

输入

第一行一个数 n,表示矩阵大小。(n ≤ 1000)

接下来 n 行,每行 n 个数,表示这个矩阵。矩阵中的数在0到108之间。

输出

一行一个数表示最大的福字的大小。

样例输入
4
1 2 3 0
2 3 4 0
3 4 5 0
0 0 0 0
样例输出
3

思路:

动态规划的题目,关键的部分是,福字为正方形,如果a[i][j]位置的数满足:

a[i][j]=a[i-1][j]+1=a[i][j-1]+1=a[i-1][j-1]+2

状态转移方程dp[i][j]=min(a[i-1][j],a[i][j-1],a[i-1][j-1])+1

else

dp[i][j]=1;

AC代码:

 1 #include "iostream"
 2 #include "algorithm"
 3 using namespace std;
 4 
 5 int dp[1001][1001], a[1001][1001];
 6 int ans;
 7 
 8 int main()
 9 {
10     int n;
11     cin >> n;
12     for (int i = 1; i <= n; i++)
13     {
14         for (int j = 1; j <= n; j++)
15         {
16             cin >> a[i][j];
17         }
18     }
19 
20     for (int i = 1; i <= n; i++)
21     {
22         for (int j = 1; j <= n; j++)
23         {
24             if ((a[i][j] == a[i - 1][j] + 1) && (a[i][j] == a[i][j - 1] + 1) && (a[i][j] == a[i - 1][j - 1] + 2))
25                 dp[i][j] = min(min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) + 1;
26             else
27                 dp[i][j] = 1;
28 
29             ans = max(ans, dp[i][j]);
30         }
31     }
32 
33     cout << ans;
34 }
原文地址:https://www.cnblogs.com/SeekHit/p/6486299.html