洛谷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\n", 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\n", ans); 30 return 0; 31 }