BFS — 最小方案数

Posted asdfknjhu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BFS — 最小方案数相关的知识,希望对你有一定的参考价值。

https://www.bilibili.com/video/av32546525 代码与思路来自此

 

题目是:求 n 最少能表示成几个平方数的和

由于有 1*1=1 这个数,所以问题一定有解,因为 1 可以组成所有正整数

 

其中视频用到了宽搜,我是一点也没想到这种方法。

①  把 0 作为起始点,0+一个平方数 作为下一层,0+一个平方数+一个平方数  作为再下一层,由此可组成一个树

 

②  然后标记距离  0 距离为 0,0+一个平方数 距离为 1,0+一个平方数+一个平方数 距离为 2

 

③  所以 队列里面放的数为  0,0+一个平方数,0+一个平方数+一个平方数,这样循环结束的条件是 队列里 最先出现的那个 n

所以可以 是 那个取队首的变量 vertex == n

 

下面是我画的树:

技术图片

 

 下面是代码:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<vector>
#include<queue>
using namespace std;
int BFS(int n)
{
	queue<int>q;
	vector<int>dist(n + 1, INT_MAX);   // 考虑极端条件 平方数全部由 1 组成,且还需要储存下一层 所以需要 n+1
	q.push(0);
	dist[0] = 0;

	while (q.size() > 0)
	{
		int vertex = q.front();    // 结点
		q.pop();

		if (vertex == n)
			return dist[vertex];
		for (int i = 1; i*i + vertex <= n; i++)
		{
			int next = i*i + vertex;          // 下一个结点
			if (dist[next] > dist[vertex] + 1)   // dist[next] 距离已经被标记好了,就是 dist[next] == dist[i] + 1 ,这就不用再放进队列里面了,因为这个数一定不会比之更小
			{
				q.push(next);
				dist[next] = dist[vertex] + 1;
			}
		}
	}

}
int main(void)
{
	int n;
	while (scanf("%d", &n) != EOF)
	{
		printf("%d
", BFS(n));
	}
	system("pause");
	return 0;
}

  

 

以上是关于BFS — 最小方案数的主要内容,如果未能解决你的问题,请参考以下文章

将数字减少到 1 的最小步骤数

bfs最短路与最小步数模型

Vijos 1206 CoVH之再破难关 BFS与位运算

[bfs] aw1107. 魔板(bfs最小步数模型+代码细节+代码功底+好题)

CodeForces 558C.Amr and Chemistry(多源BFS)

5916. 转化数字的最小运算数