BFS, D.最小相似度,牛客练习赛41,
由于M只有20,所以我们知道状态数一共只有2^20,我们如果能算出每个状态和给定n个字符串相似度的最大值,这道题就解决了。首先我们知道所有n个串最初的dp值为m,通过bfs,把每个串丢进队列一次,每个串改变每一位得到新的字符串,相同位少了一个 , 即相似度减一,更新那些没出现过的串的dp值再丢进队列,就可以保证当前步数为最大相似度。而且保证每个串只进一次队列
#include<iostream>
#include<cstdio>
#include<memory.h>
#include<queue>
using namespace std;
int deep[1 << 21];
int INF = 0x3f3f3f3f;
int main()
{
int n, m;
queue<int> q;
scanf("%d %d", &n, &m);
memset(deep, INF, sizeof(deep));
for(int i = 0; i < n; i++)
{
char s[30];
scanf("%s", &s);
int num = 0;
for(int j = 0; j < m; j++)
num = (num << 1) + s[j] - '0';
if(deep[num] == INF)
{
deep[num] = m;
q.push(num);
}
}
int ans = INF;
while(!q.empty()) //总共就2^20种状态, 用ans保存最小值, 若某一个值到其中一个状态的步数最小, 类
//似bfs, 其他值到这一状态的步数一定不小于ans, 为最小值
{
int t = q.front();
q.pop();
ans = min(ans, deep[t]);
for(int i = 0; i < m; i++)
{
int tmp = t^(1 << i);
if(deep[tmp] == INF)
{
deep[tmp] = deep[t] - 1;
q.push(tmp);
}
}
}
printf("%d", ans);
}