P10766
Link_Cut_Y · · 题解
怎么会有这么蠢的紫题。
首先挖掘一下题目的性质。首先一个比较典的就是,翻转区间之间互不相交,覆盖区间之间互不相交。另外比较难观察的是,所有覆盖都可以在翻转后再进行,他们可以在相同步数内得到相同结果。
为什么是这样呢?假设覆盖的区间包含在翻转的区间内,假设先翻转,再覆盖成
所以我们考虑,将原序列先全用覆盖操作,变成形如若干段与
由于翻转可以全在覆盖后做,我们不妨设
分类讨论进行转移,这里的分类讨论就不细说了,大概就是如果
read(n);
scanf("%s", s + 1);
scanf("%s", t + 1);
memset(f, 0x3f, sizeof f);
f[0][0][2] = 0;
rop(i, 0, n) {
if (s[i + 1] == t[i + 1]) {
if (s[i + 1] == '0') {
chkmin(f[i + 1][0][0], f[i][0][0]);
rep(j, 0, 2) chkmin(f[i + 1][0][2], f[i][0][j]);
chkmin(f[i + 1][0][0], f[i][1][0]);
rep(j, 0, 2) chkmin(f[i + 1][0][2], f[i][1][j]);
chkmin(f[i + 1][1][1], f[i][1][1]);
chkmin(f[i + 1][1][1], f[i][1][0] + 1);
chkmin(f[i + 1][1][1], f[i][1][2] + 1);
chkmin(f[i + 1][1][1], f[i][0][1] + 1);
chkmin(f[i + 1][1][1], f[i][0][0] + 2);
chkmin(f[i + 1][1][1], f[i][0][2] + 2);
} else if (s[i + 1] == '1') {
chkmin(f[i + 1][0][1], f[i][0][1]);
rep(j, 0, 2) chkmin(f[i + 1][0][2], f[i][0][j]);
chkmin(f[i + 1][0][1], f[i][1][1]);
rep(j, 0, 2) chkmin(f[i + 1][0][2], f[i][1][j]);
chkmin(f[i + 1][1][0], f[i][1][0]);
chkmin(f[i + 1][1][0], f[i][1][1] + 1);
chkmin(f[i + 1][1][0], f[i][1][2] + 1);
chkmin(f[i + 1][1][0], f[i][0][0] + 1);
chkmin(f[i + 1][1][0], f[i][0][1] + 2);
chkmin(f[i + 1][1][0], f[i][0][2] + 2);
}
} else {
if (s[i + 1] == '0') {
chkmin(f[i + 1][1][0], f[i][1][0]);
rep(j, 0, 2) chkmin(f[i + 1][1][2], f[i][1][j]);
chkmin(f[i + 1][1][0], f[i][0][0] + 1);
rep(j, 0, 2) chkmin(f[i + 1][1][2], f[i][0][j] + 1);
chkmin(f[i + 1][0][1], f[i][1][1]);
chkmin(f[i + 1][0][1], f[i][1][0] + 1);
chkmin(f[i + 1][0][1], f[i][1][2] + 1);
chkmin(f[i + 1][0][1], f[i][0][1]);
chkmin(f[i + 1][0][1], f[i][0][0] + 1);
chkmin(f[i + 1][0][1], f[i][0][2] + 1);
} else if (s[i + 1] == '1') {
chkmin(f[i + 1][1][1], f[i][1][1]);
rep(j, 0, 2) chkmin(f[i + 1][1][2], f[i][1][j]);
chkmin(f[i + 1][1][1], f[i][0][1] + 1);
rep(j, 0, 2) chkmin(f[i + 1][1][2], f[i][0][j] + 1);
chkmin(f[i + 1][0][0], f[i][1][0]);
chkmin(f[i + 1][0][0], f[i][1][1] + 1);
chkmin(f[i + 1][0][0], f[i][1][2] + 1);
chkmin(f[i + 1][0][0], f[i][0][0]);
chkmin(f[i + 1][0][0], f[i][0][1] + 1);
chkmin(f[i + 1][0][0], f[i][0][2] + 1);
}
}
}
int ans = 0x3f3f3f3f;
rep(j, 0, 1) rep(k, 0, 2) chkmin(ans, f[n][j][k]);
printf("%lld\n", ans);
我真是分类讨论大师。