P1460 [USACO2.1]健康的荷斯坦奶牛 Healthy Holsteins做题笔记

感觉自己 \(BFS\) 还是太弱了,考试时只会写 \(DFS\),连 \(BFS\) 的基本思路和原理都比较模糊,所以最近开始练 \(BFS\)。这道题鸽了很久了,以前练 \(BFS\) 的时候看题解觉得码量偏大就换题了,咕到了现在。开始时没想出来,可能有以前看题的心理阴影在里面吧,然后就看了题解。思路是建一个结构体的队列,结构体里两个数组一个变量,分别表示当前各种维他命的量、用了哪几种饲料以及用的饲料总数,先把只用一种饲料的情况按字典序入队,进行 \(BFS\),判断是否有单个饲料满足情况,即每一种维他命量都大于所需的维他命最小量,如果有就输出并停止搜索,否则遍历字典序在当前饲料后面的饲料,把后面的一种饲料加入当前饲料中,将所有加入饲料的情况入队。注意:不能在直接表示当前饲料维他命量的数组上直接加上后来的饲料,这会造成累加,无法保证饲料的总数最小,要用一个结构体备份表示当前饲料的结构体,在加后面的饲料时把当前饲料赋值为备份的当前饲料加后来的饲料。

#include <bits/stdc++.h>
  using namespace std;
int m,n,a[20][30],b[30],i,j;
bool v;
struct xy{
	int x[30],y[400],z;
}t,u;
queue<xy>q;
void bfs()
{
	int k,l;
	for (k=1;k<=n;k++)
	{
		for (l=1;l<=m;l++)
		{
			t.x[l]=a[k][l];
		}
		t.y[1]=k;
		t.z=1;
		q.push(t);
	}
	while (!q.empty())
	{
		t=q.front();
		u=q.front();
		q.pop();
		v=1;
		for (k=1;k<=m;k++)
		{
			if (u.x[k]<b[k])
			{
				v=0;
				break;
			}
		}
		if (v)
		{
			cout<<u.z<<" ";
			for (k=1;k<=t.z;k++)
			{
				cout<<u.y[k]<<" ";
			}
			cout<<endl;
			return;
		}
		for (k=u.y[u.z]+1;k<=n;k++)
		{
			for (l=1;l<=m;l++)
			{
				t.x[l]=u.x[l]+a[k][l];
			}
			t.z=u.z+1;
			t.y[t.z]=k;
			q.push(t);
		}
	}
}
int main()
{
	ios::sync_with_stdio(0); cin.tie(nullptr);
	cin>>m;
	for (i=1;i<=m;i++)
	{
		cin>>b[i];
	}
	cin>>n;
	for (i=1;i<=n;i++)
	{
		for (j=1;j<=m;j++)
		{
			cin>>a[i][j];
		}
	}
	bfs();
	return 0;
}
posted @ 2022-06-06 10:57  Jason142  阅读(93)  评论(0编辑  收藏  举报