专栏文章

CF225C Barcode

CF225C题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miow6j1z
此快照首次捕获于
2025/12/03 02:08
3 个月前
此快照最后确认于
2025/12/03 02:08
3 个月前
查看原文
容易发现字符是如何在矩阵中分配的与答案无关,实际上只需要处理列与列之间的关系。
于是可以将问题抽象为:将一个长度为 mm 的序列染成两种颜色,代价已知,且染色后的序列连续相同颜色的长度必须在 [x,y][x,y] 中,求最小代价。
问题转换为线性,染色的代价是显然的。
考虑 DP。
dpi,1/0,jdp_{i, 1/0, j} 表示将第 ii 位染成 1/01/0,到这一位已经连续 jj 个颜色相同的最小代价。
状态转移方程:
{dpi,c,1=minj=xydis+dpi1,c1,jdpi,c,j[2,y]=dis+dpi1,c,j1\begin{cases} dp_{i, c, 1} = \min \limits _{j = x} ^y dis + dp_{i - 1, c \oplus 1, j} \\ dp_{i, c, j \in[2, y] = dis + dp_{i - 1, c, j - 1}} \end{cases}
n,m,x,yn,m,x,y 同阶,时间复杂度 O(n2)O(n ^ 2)

代码

CPP
CI N = 1e3 + 5;
int n, m, x, y, ans = 1e9, dp[N][2][N], dis[2][N];
char ch[N][N];
signed main() {
	n = read(), m = read(), x = read(), y = read();
	rep(j, 1, n) arrin(ch[j], m + 1);
	rep(j, 1, m) rep(i, 1, n) dis[0][j] += ch[i][j] == '.', dis[1][j] += ch[i][j] == '#';
	mem(dp, 0x3f);
	dp[1][0][1] = dis[0][1], dp[1][1][1] = dis[1][1];
	rep(i, 2, m) rep(c, 0, 1) {
		rep(j, x, y) dp[i][c][1] = std::min(dp[i][c][1], dis[c][i] + dp[i - 1][!c][j]);
		rep(j, 2, y) dp[i][c][j] = dis[c][i] + dp[i - 1][c][j - 1];
	}
	rep(i, x, y) ans = std::min({ ans, dp[m][0][i], dp[m][1][i] });
	print(ans);
	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...