题目链接:https://codeforces.com/problemset/problem/1391/D
分析
可以发现情况为 4 × 4 4\times4 4×4以及更大时,不存在符合要求的矩阵,所以只需要判断 n = 1 , 2 , 3 n=1, 2, 3 n=1,2,3三种情况:
- n = = 1 n==1 n==1:不存在长度是偶数的方阵,答案即 0 0 0
- n = = 2 n==2 n==2:每列 1 1 1的数量须是奇偶交错,两种情况试一遍即可
- n = = 3 n==3 n==3:定义 d p [ i ] [ a ] [ b ] [ c ] dp[i][a][b][c] dp[i][a][b][c]表示到第 i i i列, s [ i ] [ 1 ] = = a , s [ i ] [ 2 ] = = b , s [ i ] [ 3 ] = = c s[i][1]==a,s[i][2]==b,s[i][3]==c s[i][1]==a,s[i][2]==b,s[i][3]==c时需要改动的最小次数,总共有8中情况,转移方程看代码
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define fi first
#define se second
#define lson (k << 1)
#define rson (k << 1 | 1)
const int INF = 0x3f3f3f3f;
const int N = 1e6 + 10;
const int M = 1e6 + 10;
const ll P = 1e9 + 7;
int n, m;
int f[N][2][2][2];
int s[5][N];
char ss[N];
int check(int col, int a, int b, int c)
{
return (s[1][col] != a) + (s[2][col] != b) + (s[3][col] != c);
}
void solve2()
{
int sum1 = 0;
for(int j=1;j<=m;j++)
{
int t = s[1][j] + s[2][j];
if(j % 2) sum1 += abs(t - 1);
else sum1 += min(abs(t - 0), abs(t - 2));
}
int sum2 = 0;
for(int j=1;j<=m;j++)
{
int t = s[1][j] + s[2][j];
if(j % 2 == 0) sum2 += abs(t - 1);
else sum2 += min(abs(t - 0), abs(t - 2));
}
printf("%d\n",min(sum1, sum2));
}
void solve3()
{
memset(f, INF, sizeof(f));
for(int a=0;a<=1;a++)
for(int b=0;b<=1;b++)
for(int c=0;c<=1;c++)
f[1][a][b][c] = check(1, a, b, c);
for(int i=2;i<=m;i++)
{
int t = check(i, 0, 0, 0);
f[i][0][0][0] = min({f[i - 1][1][0][1] + t, f[i - 1][0][1][0] + t});
t = check(i, 0, 0, 1);
f[i][0][0][1] = min({f[i - 1][1][0][0] + t, f[i - 1][0][1][1] + t});
t = check(i, 0, 1, 0);
f[i][0][1][0] = min({f[i - 1][0][0][0] + t, f[i - 1][1][1][1] + t});
t = check(i, 0, 1, 1);
f[i][0][1][1] = min({f[i - 1][1][1][0] + t, f[i - 1][0][0][1] + t});
t = check(i, 1, 0, 0);
f[i][1][0][0] = min({f[i - 1][0][0][1] + t, f[i - 1][1][1][0] + t});
t = check(i, 1, 0, 1);
f[i][1][0][1] = min({f[i - 1][0][0][0] + t, f[i - 1][1][1][1] + t});
t = check(i, 1, 1, 0);
f[i][1][1][0] = min({f[i - 1][1][0][0] + t, f[i - 1][0][1][1] + t});
t = check(i, 1, 1, 1);
f[i][1][1][1] = min({f[i - 1][0][1][0] + t, f[i - 1][1][0][1] + t});
}
int ans = INF;
for(int a=0;a<=1;a++)
for(int b=0;b<=1;b++)
for(int c=0;c<=1;c++)
ans = min(f[m][a][b][c], ans);
printf("%d\n",ans);
}
int main() {
scanf("%d%d",&n,&m);
if(n > 3 && m > 3)
{
for(int i=1;i<=n;i++) scanf("%s",ss);
printf("-1\n");
return 0;
}
if(n > m)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%1d",&s[j][i]);
swap(n, m);
}
else
{
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%1d",&s[i][j]);
}
if(n == 1)
{
printf("0\n");
}
else if(n == 2)
{
solve2();
}
else
{
solve3();
}
return 0;
}