每日一题31.「土」秘法地震 (二维前缀和 / DP)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了每日一题31.「土」秘法地震 (二维前缀和 / DP)相关的知识,希望对你有一定的参考价值。

补题链接:Here

题意就是要找每一个 \\(k * k\\) 的小正方形里至少有一个1的数量

显然我们可以通过二维前缀和处理出(1, 1) 到 (n, m) 的数量

然后通过枚举处理出答案,具体思想是容斥

\\(dp[i][j]\\) 为 (1, 1) 到 (n, m) 的1的数量

有递推式子 \\(dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1] + pos_{i,j} == \'1\'\\)

这个式子可以看成以下图形

image-20210522124957914

【AC代码】

const int N = 2e3 + 10;
int dp[1010][1010];
void solve() {
	int n, m, k;
	cin >> n >> m >> k;
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j <= m; ++j) {
			char ch; cin >> ch;
			dp[i][j] += (ch == \'1\');
		}
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j <= m; ++j)
			dp[i][j] += dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1];
	int ans = 0;
	for (int i = k; i <= n; i++)
		for (int j = k; j <= m; j++)
			if (dp[i][j] - dp[i - k][j] - dp[i][j - k] + dp[i - k][j - k] > 0)
				ans++;
	cout << ans << "\\n";
}

这道题和蓝书上前缀和专题的一道题很像

以上是关于每日一题31.「土」秘法地震 (二维前缀和 / DP)的主要内容,如果未能解决你的问题,请参考以下文章

力扣每日一题 2000 反转单词前缀

每日一题1260. 二维网格迁移

每日一题1260. 二维网格迁移

每日一题1260. 二维网格迁移

每日一题745. 前缀和后缀搜索

每日一题 | day31(分解因数)