P1460 健康的荷斯坦奶牛 Healthy Holsteins

P1460 健康的荷斯坦奶牛 Healthy Holsteins


题目描述

农民JOHN以拥有世界上最健康的奶牛为傲。他知道每种饲料中所包含的牛所需的最低的维他命量是多少。请你帮助农夫喂养他的牛,以保持它们的健康,使喂给牛的饲料的种数最少。

给出牛所需的最低的维他命量,输出喂给牛需要哪些种类的饲料,且所需的饲料剂量最少。

维他命量以整数表示,每种饲料最多只能对牛使用一次,数据保证存在解。

输入输出格式

输入格式:

第1行:一个整数V(1<=V<=25),表示需要的维他命的种类数。

第2行:V个整数(1<=每个数<=1000),表示牛每天需要的每种维他命的最小量。

第3行:一个整数G(1<=G<=15),表示可用来喂牛的饲料的种数。

下面G行,第n行表示编号为n饲料包含的各种维他命的量的多少。

输出格式:

输出文件只有一行,包括

牛必需的最小的饲料种数P

后面有P个数,表示所选择的饲料编号(按从小到大排列)。

如果有多个解,输出饲料序号最小的(即字典序最小)。

输入输出样例

输入样例#1:
4
100 200 300 400
3
50  50  50  50
200 300 200 300
900 150 389 399
输出样例#1:
2 1 3

说明

USACO 2.1

翻译来自NOCOW


被卡了一个小时,第一次写剪纸的蒟蒻就是我。


首先就是要枚举不重复的子集,根据测算,只需要枚举25 +24 +23  +...+1 = (25 + 1)*25/2个子集,所以时间复杂度是相当低的。
但是如果枚举成25!的子集,一定会崩掉。


我们为了避免枚举重复的子集,采取了这样的枚举自己方法(紫书里还有一种):

枚举子集内元素个数1..n,并保证子集是单调递增的。这样就能够补充不漏的枚举子集。

上代码。


#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm>

const int MAXN = 25 + 15;
const int MAXM = 15 + 15;

int n;
int min[MAXN];
int m;
int value[MAXM][MAXN];

int c[MAXN];

int num[MAXN];
bool b[MAXM];

bool IsFull[MAXN];

int ans;

int cnt;
bool ok;

void dfs(int step,int pre)
{
	if(ok)return;
	if(step > cnt + 1) return;
	if(step == cnt + 1)
	{
		for(int i = 1;i <= n;i ++)
		{
			int sum = 0;
			for(int j = 1;j <= cnt;j ++)
			{
				sum += value[num[j]][i];
			}
			if(sum < min[i])return;
		}
		ans = cnt;
		ok  = true;
		return;
	}

	for(int i = 1;i <= m;i ++)
	{
		if(ok)return;
		if(i <= pre)continue; 
		if(!b[i])
		{
			num[step] = i;
			b[i] = true;
			dfs(step + 1,i);
			b[i] = false;
		}
	}
}	

int main()
{
	freopen("data.txt", "r", stdin);
	ans = 99999999;
	scanf("%d", &n);
	for(int i = 1;i <= n;i ++)
	{
		scanf("%d", &min[i]);
	}
	scanf("%d", &m);
	for(int i = 1;i <= m;i ++)
	{
		for(int j = 1;j <= n;j ++)
		{
			scanf("%d", &value[i][j]);
		}
	}
	for(int i = 1;i <= m;i ++)
	{
		cnt ++;
		dfs(1,0);
		if(ok) break;
	}	
	printf("%d ", ans);
	for(int i = 1;i <= ans;i ++)
	{
		printf("%d ", num[i]);
	}
	return 0;
}



posted @ 2017-03-08 15:43  嘒彼小星  阅读(358)  评论(0编辑  收藏  举报