GUO120822 @ 2024-11-23 21:00:10
#include<bits/stdc++.h>
using namespace std;
/*
可以直接枚举哪几列 OK 2^18。
然后先不考虑复杂度。
枚举行,每一行考虑每一个合法列的东西。
每一行考虑合法列是否使其合法。
然后枚举
*/
const int N=350,inf=0x3f3f3f3f;
int n,m,i,j;
char a[N][N],t[N][N];
bool r;
bool b[N],p[N];
int dp[N][N],v1[N],v2[N],v3[N],v4[N],ans[N][N];
int fun1(int x)
{
int i,ans=0;
for (i=1;i<=m;i++)
{
if (b[i]) ans+=min((a[x][i]!='0')+(a[n-x+1][i]!='0'),(a[x][i]!='1')+(a[n-x+1][i]!='1'));
}
return ans;
}
int fun2(int x)
{
int i,ans=0;
for (i=1;i<=m/2;i++)
{
if (!b[i]&&!b[m-i+1]) ans+=min((a[x][i]!='0')+(a[x][m-i+1]!='0'),(a[x][i]!='1')+(a[x][m-i+1]!='1'));
else if (b[i]&&!b[m-i+1]) ans+=min((a[x][i]!='0')+(a[x][m-i+1]!='0')+(a[n-x+1][i]!='0'),(a[x][i]!='1')+(a[x][m-i+1]!='1')+(a[n-x+1][i]!='1'));
else if (!b[i]&&b[m-i+1]) ans+=min((a[x][i]!='0')+(a[x][m-i+1]!='0')+(a[n-x+1][m-i+1]!='0'),(a[x][i]!='1')+(a[x][m-i+1]!='1')+(a[n-x+1][m-i+1]!='1'));
else ans+=min((a[x][i]!='0')+(a[x][m-i+1]!='0')+(a[n-x+1][i]!='0')+(a[n-x+1][m-i+1]!='0'),(a[x][i]!='1')+(a[x][m-i+1]!='1')+(a[n-x+1][i]!='1')+(a[n-x+1][m-i+1]!='1'));
}
if (m&1)
{
if (b[(m+1)/2]) ans+=min((a[x][(m+1)/2]!='0')+(a[n-x+1][(m+1)/2]!='0'),(a[x][(m+1)/2]!='1')+(a[n-x+1][(m+1)/2]!='1'));
}
return ans;
}
int fun3(int x)
{
int i,ans=0;
for (i=1;i<=m/2;i++)
{
if (!b[i]&&!b[m-i+1]) ans+=min((a[n-x+1][i]!='0')+(a[n-x+1][m-i+1]!='0'),(a[n-x+1][i]!='1')+(a[n-x+1][m-i+1]!='1'));
else if (b[i]&&!b[m-i+1]) ans+=min((a[n-x+1][i]!='0')+(a[n-x+1][m-i+1]!='0')+(a[x][i]!='0'),(a[n-x+1][i]!='1')+(a[n-x+1][m-i+1]!='1')+(a[x][i]!='1'));
else if (!b[i]&&b[m-i+1]) ans+=min((a[n-x+1][i]!='0')+(a[n-x+1][m-i+1]!='0')+(a[x][m-i+1]!='0'),(a[n-x+1][i]!='1')+(a[n-x+1][m-i+1]!='1')+(a[x][m-i+1]!='1'));
else ans+=min((a[x][i]!='0')+(a[x][m-i+1]!='0')+(a[n-x+1][i]!='0')+(a[n-x+1][m-i+1]!='0'),(a[x][i]!='1')+(a[x][m-i+1]!='1')+(a[n-x+1][i]!='1')+(a[n-x+1][m-i+1]!='1'));
}
if (m&1)
{
if (b[(m+1)/2]) ans+=min((a[x][(m+1)/2]!='0')+(a[n-x+1][(m+1)/2]!='0'),(a[x][(m+1)/2]!='1')+(a[n-x+1][(m+1)/2]!='1'));
}
return ans;
}
int fun4(int x)
{
int i,ans=0;
for (i=1;i<=m/2;i++)
{
if (!b[i]&&!b[m-i+1])
{
ans+=min((a[n-x+1][i]!='0')+(a[n-x+1][m-i+1]!='0'),(a[n-x+1][i]!='1')+(a[n-x+1][m-i+1]!='1'));
ans+=min((a[x][i]!='0')+(a[x][m-i+1]!='0'),(a[x][i]!='1')+(a[x][m-i+1]!='1'));
}
else ans+=min((a[x][i]!='0')+(a[x][m-i+1]!='0')+(a[n-x+1][i]!='0')+(a[n-x+1][m-i+1]!='0'),(a[x][i]!='1')+(a[x][m-i+1]!='1')+(a[n-x+1][i]!='1')+(a[n-x+1][m-i+1]!='1'));
}
if (m&1)
{
if (b[(m+1)/2]) ans+=min((a[x][(m+1)/2]!='0')+(a[n-x+1][(m+1)/2]!='0'),(a[x][(m+1)/2]!='1')+(a[n-x+1][(m+1)/2]!='1'));
}
return ans;
}
void fun()
{
int i,j,cnt=0,t=(n+1)/2;
for (i=0;i<=t;i++)
{
for (j=0;j<=n;j++) dp[i][j]=inf;
}
for (i=1;i<=t;i++)
{
v1[i]=fun1(i);
v2[i]=fun2(i);
v3[i]=fun3(i);
v4[i]=fun4(i);
if (n%2==1&&i==t) v4[i]=inf;
}
dp[0][0]=0;
for (i=1;i<=t;i++)
{
for (j=0;j<=n;j++)
{
dp[i][j]=dp[i-1][j]+v1[i];
if (j>=1) dp[i][j]=min(dp[i][j],dp[i-1][j-1]+v2[i]);
if (j>=1) dp[i][j]=min(dp[i][j],dp[i-1][j-1]+v3[i]);
if (j>=2) dp[i][j]=min(dp[i][j],dp[i-1][j-2]+v4[i]);
}
}
for (i=1;i<=m;i++)
{
if (b[i]) cnt++;
}
for (i=0;i<=n;i++)
{
for (j=0;j<=cnt;j++) ans[i][j]=min(ans[i][j],dp[t][i]);
}
}
void dfs(int dep)
{
if (dep>m)
{
fun();
return;
}
b[dep]=false;
dfs(dep+1);
b[dep]=true;
dfs(dep+1);
}
int main()
{
freopen("dawn.in","r",stdin);
freopen("dawn.out","w",stdout);
scanf("%d%d",&n,&m);
for (i=1;i<=n;i++) scanf("%s",t[i]+1);
if (n<m)
{
r=true;
for (j=1;j<=m;j++)
{
for (i=1;i<=n;i++) a[j][i]=t[i][j];
}
swap(n,m);
}
else
{
for (i=1;i<=n;i++)
{
for (j=1;j<=m;j++) a[i][j]=t[i][j];
}
}
for (i=0;i<=n;i++)
{
for (j=0;j<=m;j++) ans[i][j]=inf;
}
dfs(1);
if (!r)
{
for (i=0;i<=n;i++)
{
for (j=0;j<=m;j++) printf("%d ",ans[i][j]);
printf("\n");
}
}
else
{
for (i=0;i<=m;i++)
{
for (j=0;j<=n;j++) printf("%d ",ans[j][i]);
printf("\n");
}
}
return 0;
}
by ltz761222 @ 2024-11-23 21:02:19
有题目吗?去云斗学院了。
by GUO120822 @ 2024-11-23 21:11:57