1. 程式人生 > >#126-(EZOI搜尋練習)[BFS]健康的荷斯坦奶牛

#126-(EZOI搜尋練習)[BFS]健康的荷斯坦奶牛

Description

農民JOHN以擁有世界上最健康的奶牛為傲。他知道每種飼料中所包含的牛所需的最低的維他命量是多少。請你幫助農夫餵養他的牛,以保持它們的健康,使餵給牛的飼料的種數最少。

給出牛所需的最低的維他命量,輸出餵給牛需要哪些種類的飼料,且所需的飼料劑量最少。

維他命量以整數表示,每種飼料最多隻能對牛使用一次,資料保證存在解。

Input

第1行:一個整數V(1<=V<=25),表示需要的維他命的種類數。

第2行:V個整數(1<=每個數<=1000),表示牛每天需要的每種維他命的最小量。

第3行:一個整數G(1<=G<=15),表示可用來喂牛的飼料的種數。

下面G行,第n行表示編號為n飼料包含的各種維他命的量的多少。

Output

輸出檔案只有一行,包括

牛必需的最小的飼料種數P

後面有P個數,表示所選擇的飼料編號(按從小到大排列)。

如果有多個解,輸出飼料序號最小的(即字典序最小)。

Sample Input

4
100 200 300 400
3
50  50  50  50
200 300 200 300
900 150 389 399

Sample Output

2 1 3

直接BFS(是有點複雜)

#include <iostream>
#include <string>
#include <vector>
#include <queue>

#define SIZE 30

using namespace std;

struct node
{
	string s; // 要輸出的字串
	vector<int> need; // 還需要的維他命數量
	int limit, dis;
};

queue<node> q;
vector<int> temp, u;
string s;
int a[SIZE][SIZE];

bool check(vector<int> v) // 檢查是否滿足條件
{
	int i;
	
	for (i = 0; i < v.size(); ++i)
	{
		if (v[i] > 0)
		{
			return false;
		}
	}
	
	return true;
}

string inttostring(int x) // 把整形轉換為字串
{
	string res = "";
	
	while (x)
	{
		res = char (x % 10 + '0') + res;
		x /= 10;
	}
	
	return res;
}

int main(void)
{
	int m, n, i, j, x, dis, limit;
	
	scanf("%d", &m);
	for (i = 0; i < m; ++i)
	{
		scanf("%d", &x);
		temp.push_back(x);
	}
	scanf("%d", &n);
	for (i = 1; i <= n; ++i)
	{
		for (j = 0; j < m; ++j)
		{
			scanf("%d", &a[i][j]);
		}
	}
	
	q.push({"", temp, 1, 0});
	while (!q.empty()) // BFS
	{
		dis = q.front().dis + 1;
		u = q.front().need;
		s = q.front().s;
		limit = q.front().limit;
		q.pop();
		for (i = limit; i <= n; ++i)
		{
			temp = u;
			for (j = 0; j < m; ++j)
			{
				temp[j] -= a[i][j];
			}
			if (check(temp))
			{
				printf("%d ", dis);
				cout << s + inttostring(i); // 輸出結果
				return 0;
			}
			q.push({s + inttostring(i) + " ", temp, i + 1, dis});
		}
	}
	
	return 0;
}