专栏文章
题解:AT_abc442_f [ABC442F] Diagonal Separation 2
AT_abc442_f题解参与者 15已保存评论 14
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 14 条
- 当前快照
- 1 份
- 快照标识符
- @mlgxs1t3
- 此快照首次捕获于
- 2026/02/11 02:30 上周
- 此快照最后确认于
- 2026/02/11 02:30 上周
前言
赛时该死的 ABC 网络给我卡没了,结果导致我在赛后一分钟 F 题 AC 了,不过比赛已经结束了,为此感到十分不幸。
为了弥补不幸,本五年级蒟蒻还是又来写一篇题解来安慰一下我吧。
题目大意
一读题就发现应该不难,可谓最简单的 F 题。
题目就是说有一个 的方格,每个格子要么是
.,要么是 #。现在需要让你把一些方格的颜色替换成另一个颜色(重新涂色),但是必须保证每一行的前一连续的部分是一个颜色,后一部分都是另一个颜色。此外,列也一样。解题思路
我们为了快速计算修改代价,因此可以用前缀和来预处理每一行的操作参数:
- 这里用 来表示在第 行中前 个格子中原本是
.的数量(.也可以说是白色)。 - 表示第 行中原本是
.的总数。(当然如果你不想要的话也可以写 进行替换,这里只是为了方便)。 我们可以使用一下代码来进行计算:
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++) pre[i][j]=pre[i][j-1]+(c[i][j]=='.');
s[i]=pre[i][n];
}
这里没什么难点就不详细讲了,就是普通的前缀和。
那么我们求出了这两个参数以后,后面计算我们需要的花费就很简单了。
设对于第 行,中间进行分段的点为 ,则:
- 在前 个格子中,初始为黑色的需要改成白色:。
- 后 个格子中,初始为白色的需要改成黑色:。
所以总花费为 ,将该式简化可得 。这里为了后边的讲解,我们将总花费设为 。
接下来就可以开始考虑动态规划。
众所周知,由于我们的行分界点一定是非递减的的,因此第 行的分界点 必须满足 。
因此不难推导出状态转移方程:
然而我们发现,直接计算是 是一定会超时的,就算对于 也会,因此我们接下来考虑优化。
注意到对于固定的 ,我们需要对每个 求 的最小值。因此我们不难发现可以预处理一下前缀最小值。这里前缀最小值的数组为 。因此方程推导:
因此我们的 数组新的状态转移方程也就得来了:
具体内部的实现我在这里总结了一下:
- 对于每一行 ,我们可以先计算这一行所有 的 总花费,记作 。
- 从上到下计算 数组:。
- 更新 。这里的 其实跟刚才的 含义一模一样。
然后要注意 数组的初始化。先可以初始化第 行,。
最后的答案也就是:
这样我们就简单高效的解决了问题,代码时间复杂度为 ,不会超时。
Code
代码:
CPP#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=5010,INF=1e18;
int n;
char c[N][N];
int pre[N][N],s[N];
int dp[N][N];
int p[N];
int d[N];
int ans=INF;
signed main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++) cin>>c[i][j];
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++) pre[i][j]=pre[i][j-1]+(c[i][j]=='.');
s[i]=pre[i][n];
}
for(int i=0;i<=n;i++)
{
dp[1][i]=(i-pre[1][i])+(s[1]-pre[1][i]);
}
for(int i=2;i<=n;i++)
{
for(int j=0;j<=n;j++) p[j]=(j-pre[i][j])+(s[i]-pre[i][j]);
d[n]=dp[i-1][n];
for(int j=n-1;j>=0;j--) d[j]=min(d[j+1],dp[i-1][j]);
for(int j=0;j<=n;j++) dp[i][j]=d[j]+p[j];
}
for(int j=0;j<=n;j++)
{
if(dp[n][j]<ans) ans=dp[n][j];
}
cout<<ans;
return 0;
}
具体的上面思路已经讲的很清楚了,就不写注释了。
end
感谢大家的阅读,我也是写的应该很清楚了,花费了很多心思。纪念一下第一次过 F 题。
希望管理大大过。
相关推荐
评论
共 14 条评论,欢迎与作者交流。
正在加载评论...