信友队T1求调
  • 板块学术版
  • 楼主GUO120822
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/11/23 13:00
  • 上次更新2024/11/23 15:33:01
查看原帖
信友队T1求调
704562
GUO120822楼主2024/11/23 13:00
#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;i++) 
	{
		if (b[i]) 
		{
			if (!b[m-i+1]||i<=(m+1)/2) ans+=min((a[x][i]!='0')+(a[n-x+1][i]!='0')+(a[x][m-i+1]!='0'),(a[x][i]!='1')+(a[n-x+1][i]!='1')+(a[x][m-i+1]!='1'));
			else ans+=min((a[x][i]!='0')+(a[n-x+1][i]!='0'),(a[x][i]!='1')+(a[n-x+1][i]!='1'));
		}
	}
	for (i=1;i<=m;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'));
	}
	return ans;
}
int fun3(int x)
{
	int i,ans=0;
	for (i=1;i<=m;i++) 
	{
		if (b[i]) 
		{
			if (!b[m-i+1]||i<=(m+1)/2) ans+=min((a[x][i]!='0')+(a[n-x+1][i]!='0')+(a[n-x+1][m-i+1]!='0'),(a[x][i]!='1')+(a[n-x+1][i]!='1')+(a[n-x+1][m-i+1]!='1'));
			else ans+=min((a[x][i]!='0')+(a[n-x+1][i]!='0'),(a[x][i]!='1')+(a[n-x+1][i]!='1'));
		}
	}
	for (i=1;i<=m;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'));
	}
	return ans;
}
int fun4(int x)
{
	int i,ans=0;
	for (i=1;i<=m;i++) 
	{
		if (b[i]) 
		{
			if (!b[m-i+1]||i<=(m+1)/2) 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'));
			else ans+=min((a[x][i]!='0')+(a[n-x+1][i]!='0'),(a[x][i]!='1')+(a[n-x+1][i]!='1'));
		}
	}
	for (i=1;i<=m;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'));
	}
	for (i=1;i<=m;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'));
	}
	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()
{
	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;
}
2024/11/23 13:00
加载中...