神奇的bfs做法:
对于每个串si,枚举所有的串x
(1<=i<=n)
第一层SIM(si,x)=m,即本身
第二层SIM(si,x)=m-1,
第三层SIM(si,x)=m-2.....
假设SIM(si,x)=v,并且x没有被访问过,那么x必然是可行且更优的,因为使得SIM(si,x)=v+1,v+2.....m的x都被枚举过了,
以x去和n个串计算SIM,得到的值必定<=v
用dp[sta]记忆化搜索,如果sta作为最佳答案T,那么dp[sta]就是sta对n个串分别求SIM值中的最大值
#include<bits/stdc++.h> #define RD1(x) scanf("%d",&x) #define RD2(x,y) scanf("%d %d",&x,&y) #define RD3(x,y,z) scanf("%d %d %d",&x,&y,&z) #define RDL1(x) scanf("%lld",&x) #define RDL2(x,y) scanf("%lld %lld",&x,&y) #define RDL3(x,y,z) scanf("%lld %lld %lld",&x,&y,&z) #define CLR(x) memset(x,0,sizeof(x)) #define NEG(x) memset(x,0xff,sizeof(x)) #define maxm (1111+10) #define maxn (1000000+10) #define lson (rt<<1) #define rson (rt<<1|1) #define mod (100000007) #define pi acos(-1) #define eps 1e-14 #define acc ios::sync_with_stdio(false);cin.tie(0) #define inf 0x3f3f3f3f #define INF(x) memset(x,inf,sizeof(x)) #define CLRQ(Q) while(!(Q).empty())(Q).pop() #define see(x) (cerr<<(#x)<<'='<<(x)<<' ') #define NL printf("\n") #define fi freopen("C:\\Users\\Administrator\\Desktop\\in","r",stdin) #define fo freopen("C:\\Users\\Administrator\\Desktop\\out","w",stdout) using namespace std; typedef long long ll; typedef unsigned long long ull; int n,m,a[maxn];char buf[30]; queue<int>Q; int dp[1<<21]; int main() { INF(dp); acc;cin>>n>>m; for(int i=1;i<=n;i++) { cin>>buf;for(int j=m-1;j>=0;j--) { a[i]<<=1; a[i]|=buf[j]-'0'; } Q.push(a[i]);dp[a[i]]=m; } int ans=m; while(!Q.empty()) { int u=Q.front();Q.pop(); ans=min(ans,dp[u]); for(int i=0;i<m;i++) { int v=u^1<<i; if(dp[v]==inf) { Q.push(v);dp[v]=dp[u]-1; } } } cout<<ans; return 0; }