题意
n 条木板,每条木板都被分成 m 段且每一段都有要涂的颜色,有 t 次机会涂色,每次可以选择一条木板的连续一段涂成同一种颜色,问最多可以涂对多少段。
solution
考虑四维dp的做法。 代表到第 条第 段时涂 次,当前段涂红或蓝的最大正确数,可以得到转移方程:
当 (属于当前木板第一段) 时,由上一个木板转移过来:
否则,由当前木板的上一段转移过来:
最后结果显然为 。
时间复杂度 ,空间上可以使用滚动数组压维,空间复杂度为 。
Code
#include <bits/stdc++.h> using namespace std; const int N = 55; char s[N][N]; int n, m, t, dp[2][N][N * N][2]; int main() { scanf("%d%d%d", &n, &m, &t); for (int i = 1; i <= n; i++) scanf("%s", s[i] + 1); for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) for (int k = 1; k <= t; k++) for (int l = 0; l <= 1; l++) { if (j == 1) dp[i & 1][j][k][l] = max(dp[(i - 1) & 1][m][k - 1][0], dp[(i - 1) & 1][m][k - 1][1]) + (s[i][j] == l + '0'); else dp[i & 1][j][k][l] = max(dp[i & 1][j - 1][k][l], dp[i & 1][j - 1][k - 1][l ^ 1]) + (s[i][j] == l + '0'); } printf("%d\n", max(dp[n & 1][m][t][0], dp[n & 1][m][t][1])); return 0; }