题解:AT_abc396_g [ABC396G] Flip Row or Col
思路
我们先转换一下题意:给你一个数组
我们定义
最后转移的式子如下:
当然这个式子还是太抽象了,大概说一下含义。
假设每个二进制数都是一个点,然后与之汉明距离为
我们先加上
然而算完之后却发现多算了好多。这是因为对于每条路径,都有
最终复杂度
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=18,inf=1e18;
int n,m,f[(1<<N)+2][N+2];
int ans;
signed main(){
ios::sync_with_stdio(false);cin.tie(0);
cin>>n>>m;
ans=inf;
for(int i=1;i<=n;i++){
int x=0;
for(int j=1;j<=m;j++){
char y;cin>>y;
x=(x<<1)|(y-'0');
}
f[x][0]++;
}
for(int i=1;i<=m;i++){
for(int s=0;s<1<<m;s++){
for(int j=1;j<=m;j++){
int t=s^(1<<j-1);
for(int k=i-1;k>=0;k--){
if((i^k)&1)f[s][i]+=f[t][k];
else f[s][i]-=f[s][k];
}
}
f[s][i]/=i;
}
}
for(int s=0;s<1<<m;s++){
int num=0;
for(int i=0;i<=m;i++)num+=min(i,m-i)*f[s][i];
ans=min(ans,num);
}
cout<<ans<<"\n";
return 0;
}
顺带,这题评紫真的合适吗……