洛谷1387(基础二维dp)

题目很简单,数据也很小,但是思路不妨借鉴:dp[i][j]代表以(i,j)为右下角的最长正方形边长。

类比一维里面设“以XX为结尾的最XXX(所求)”。

另外define不要乱用!尤其这种min套min,debug两行泪。

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 int n, m, ans, a, dp[105][105];
 6 
 7 int main() {
 8     scanf("%d %d", &n, &m);
 9     for (int i = 1; i <= n; i++) {
10         for (int j = 1; j <= m; j++) {
11             scanf("%d", &a);
12             if (a)    dp[i][j] = min(dp[i - 1][j - 1], min(dp[i - 1][j], dp[i][j - 1])) + 1;
13             ans = max(ans, dp[i][j]);
14         }
15     }
16     printf("%d
", ans);
17     return 0;
18 }

当然也可以无脑暴力乱搞了,二维前缀和+二分:

 1 #include <cstdio>
 2 #define min(a, b)   a < b ? a : b
 3 
 4 int n, m, ans, a[105][105], cnt[105][105];
 5 
 6 int main() {
 7     scanf("%d %d", &n, &m);
 8     for (int i = 1; i <= n; ++i)
 9         for (int j = 1; j <= m; ++j)
10             scanf("%d", &a[i][j]);
11     for (int i = 1; i <= n; ++i)
12         for (int j = 1; j <= m; ++j)
13             cnt[i][j] = cnt[i - 1][j] + cnt[i][j - 1] - cnt[i - 1][j - 1] + (a[i][j] == 0);
14 
15     int l = 0, r = min(n, m);
16     auto ok = [](int len) {
17         for (int i = 1; i + len - 1 <= n; ++i)
18             for (int j = 1; j + len - 1 <= m; ++j)
19                 if (cnt[i + len - 1][j + len - 1] - cnt[i + len - 1][j - 1] - cnt[i - 1][j + len - 1] + cnt[i - 1][j - 1] == 0)
20                     return true;
21         return false;
22     };
23     while (l <= r) {
24         int mid = (l + r) >> 1;
25         if (ok(mid)) {
26             ans = mid, l = mid + 1;
27         } else  r = mid - 1;
28     }
29     printf("%d
", ans);
30     return 0;
31 }
原文地址:https://www.cnblogs.com/AlphaWA/p/10598470.html