BFS,牛客练习赛41, D.最小相似度

传送门
在这里插入图片描述在这里插入图片描述

由于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);
}

猜你喜欢

转载自blog.csdn.net/qq_40212930/article/details/88079450