E - Don't Isolate Elements(DP,状态设计)
E - Don't Isolate Elements
题意
给出一个01矩阵,长为
合法的定义:图中不存在数量为1的连通块。
思路
显然,这就是一个对行来动态规划的问题,对于每一行,我们有两种状态,要么对其反转,要么保持原状。那大抵就是这样
代码
关于代码实现有很多细节,一个是为了处理边界问题,把边界赋值为2,这样可以省去特判边界的情况。关于正反图,可以用一个
#include <bits/stdc++.h>
using namespace std;
const int N = 1005;
int n, m;
int g[2][N][N];
int f[N][2][2]; //从1到n的最小花费,第i行的正反和第i+1行的正反
bool check(int l, int r, int u, int d, int mid)
{
return (l != mid && r != mid && u != mid && d != mid);
}
int main()
{
cin >> n >> m;
memset(f, 0x3f, sizeof f);
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= m; j ++)
cin >> g[0][i][j], g[1][i][j] = (1 - g[0][i][j]);
for(int i = 0; i <= m + 1; i ++)
g[0][0][i] = g[1][0][i] = g[0][n + 1][i] = g[1][n + 1][i] = 2;
for(int i = 0; i <= n + 1; i ++)
g[0][i][0] = g[1][i][0] = g[0][i][m + 1] = g[1][i][m + 1] = 2;
f[0][0][0] = f[0][0][1] = 0;
for(int i = 1; i <= n; i ++)
{
for(int a = 0; a < 2; a ++)
for(int b = 0; b < 2; b ++)
for(int c = 0; c < 2; c ++)
{
int flag = 0;
for(int j = 1; j <= m; j ++)
{
flag |= check(g[b][i][j - 1], g[b][i][j + 1], g[a][i - 1][j], g[c][i + 1][j], g[b][i][j]);
}
if(!flag)
f[i][b][c] = min(f[i][b][c], f[i - 1][a][b] + b);
}
}
int res = min(f[n][1][0], f[n][0][0]);
cout << (res == 0x3f3f3f3f ? -1 : res) << '\n';
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】