2.1.4 Healthy Holsteins 健康的好斯坦奶牛

2.1.4 Healthy Holsteins 健康的好斯坦奶牛

一、题目描述

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

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

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

PROGRAM NAME: holstein

INPUT FORMAT

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

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

第3 行:一个整数G(1<=G<=15),表示可用来喂牛的饲料的数量.下面G 行,第i 行表示编号为 i 饲料

包含的各种维他命的量的多少.

SAMPLE INPUT (file holstein.in)

4

100 200 300 400

3

50 50 50 50

200 300 200 300

900 150 389 399

OUTPUT FORMAT

输出文件只有一行,包括:

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

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

SAMPLE OUTPUT (file holstein.out)

2 1 3

二、解题思路

对于每种饲料,只有两种选择:喂或者不喂。因此我们可以对饲料进行标号(不用再标,用索引就行)。枚举所有索引的子集,即所有饲料的混合。测试每个子集是否符合要求(对应维他命数大于要求的数量),并保证子集的大小最小。

枚举子集的方法很多,可以采用DFS(位向量构造方法,元素在或不在子集中)、BFS;也可以用二进制法,枚举1
to 2^p-1的长度为p(总饲料数)的二进制来获得每个养料是否要,0表示不喂,1表示喂。这几种方法比较常用,注意简单常用的就比较好了,也马上容易写出来!

这里我是直接采用的刘汝佳的《算法竞赛入门经典》中的增量构造法代码,直接生成子集。自己要理解和写出程序不容易。

源程序

#include<iostream>
#include<cstdio>

using namespace std;

int N,M;
int v[25+5];
int vv[1000+10][1000+10];
int vis[25+5];
int temp[25];

int rst=25;

int isok(int *A,int cur){
	int i,j,sum;
	for (i=0;i<N;i++)	{
		sum=0;
		for (j=0;j<cur;j++){
			sum=sum+vv[A[j]][i];
		}

		if (sum<v[i])
	        return 0;
	}
	return 1;
}

void print_subset(int n, int* A, int cur) {//求元素的子集 按(索引)字典序求解,并不是按子集长度
	int i;

//  	for(i = 0; i <cur; i++) printf("%d ", A[i]); // 打印当前索引子集集合
//      printf("\n");
//
	if(isok(A,cur)&&cur<rst){
		rst=cur;
		for(i = 0; i<cur+1; i++) {
			vis[i]=A[i];
		}
	}

	int s = cur ? A[cur-1]+1 : 0; // 确定当前元素的最小可能值
	for( i = s; i < n; i++) {
		A[cur] = i;
		print_subset(n, A, cur+1); // 递归构造子集
	}
}

int main()
{
	freopen("holstein.in","r",stdin);
	freopen("holstein.out","w",stdout);

	cin>>N;
	int i,j;
	for (i=0;i<N;i++)	{
		cin>>v[i];
	}
	cin>>M;
	for (i=0;i<M;i++)
		for(j=0;j<N;j++){
			cin>>vv[i][j];
		}

	print_subset(M,temp,0);

	cout<<rst;
	for (i=0;i<rst;i++)
	{cout<<" "<<(vis[i]+1);}
	cout<<endl;

	return 0;
}

由于自身是初学者,编程能力有限,未达到专业程序员的水平,可能误导大家,请大家甄读;文字编辑也一般,文中可能会有措辞不当。博文中的错误和不足敬请读者批评指正。

时间: 2024-08-08 19:17:42

2.1.4 Healthy Holsteins 健康的好斯坦奶牛的相关文章

USACO Section 2.1 Healthy Holsteins

/* ID: lucien23 PROG: holstein LANG: C++ */ #include <iostream> #include <fstream> #include <vector> using namespace std; bool compFun(int x, int y) { int temp, i = 0; while (true) { temp = 1 << i; if (temp&x > temp&y) {

洛谷P1460 健康的荷斯坦奶牛 Healthy Holsteins

题目描述 农民JOHN以拥有世界上最健康的奶牛为傲.他知道每种饲料中所包含的牛所需的最低的维他命量是多少.请你帮助农夫喂养他的牛,以保持它们的健康,使喂给牛的饲料的种数最少. 给出牛所需的最低的维他命量,输出喂给牛需要哪些种类的饲料,且所需的饲料剂量最少. 维他命量以整数表示,每种饲料最多只能对牛使用一次,数据保证存在解. 输入输出格式 输入格式: 第1行:一个整数V(1<=V<=25),表示需要的维他命的种类数. 第2行:V个整数(1<=每个数<=1000),表示牛每天需要的每种

洛谷P1460 [USACO2.1]健康的荷斯坦奶牛 Healthy Holsteins

题目描述 农民JOHN以拥有世界上最健康的奶牛为傲.他知道每种饲料中所包含的牛所需的最低的维他命量是多少.请你帮助农夫喂养他的牛,以保持它们的健康,使喂给牛的饲料的种数最少. 给出牛所需的最低的维他命量,输出喂给牛需要哪些种类的饲料,且所需的饲料剂量最少. 维他命量以整数表示,每种饲料最多只能对牛使用一次,数据保证存在解. 输入输出格式 输入格式: 第1行:一个整数V(1<=V<=25),表示需要的维他命的种类数. 第2行:V个整数(1<=每个数<=1000),表示牛每天需要的每种

USACO-Section 2.1 Healthy Holsteins (状态压缩DFS)

描述 农民JOHN以拥有世界上最健康的奶牛为傲.他知道每种饲料中所包含的牛所需的最低的维他命量是多少.请你帮助农夫喂养他的牛,以保持它们的健康,使喂给牛的饲料的种数最少. 给出牛所需的最低的维他命量,输出喂给牛需要哪些种类的饲料,且所需的饲料剂量最少. 维他命量以整数表示,每种饲料最多只能对牛使用一次,数据保证存在解. 格式 PROGRAM NAME: holstein INPUT FORMAT: (file holstein.in) 第1行:一个整数V(1<=V<=25),表示需要的维他命的

usaco Healthy Holsteins

题意为有一头牛,它每天所需的维生素有V种,每种维生素的需求量给出,同时给出G种已知的饲料,求如何组合这些饲料可以使得牛获得足够的维生素: 给的数据范围很小,直接暴力枚举所有 /* ID: modengd1 PROG: holstein LANG: C++ */ #include <iostream> #include <stdio.h> #include <memory.h> using namespace std; int V,G,food[15][1000],cow

USACO Section2.1 Healthy Holsteins 解题报告 【icedream61】

holstein解题报告 ------------------------------------------------------------------------------------------------------------------------------------------------[题目] 你需要给一头奶牛制定最优的喂养计划. 有V种维他命,每天对于每种维他命,牛都有需要达到的指标: 同时你有G种饲料,编号依次为1到G,每种维他命在每种饲料中所蕴含的量都会给你.

【USACO 2.1】Healthy Holsteins

/* TASK: holstein LANG: C++ URL: http://train.usaco.org/usacoprob2?a=SgkbOSkonr2&S=holstein SOLVE: con[i][j]为食物i含有维生素j的量,ned[i]为需要的维生素i的量 bfs,用二进制保存状态 */ #include<cstdio> #define N 30 int v,g,ned[N],con[N][N]; int now[N]; int l,r,q[40000]; bool

USACO Healthy Holsteins DFS

使用排列组合,遍历所有可能的情况C(1)+C(2)+C(3)……C(n)= 2^G种组合 数据规模不大,暴力过去最多也就是2^15 = 23768种情况 所以就暴力咯,不过还是Debug了一会 Source Code: /* ID: wushuai2 PROG: holstein LANG: C++ */ //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include <stdio.h> #i

p1460 Healthy Holsteins

列举所有的子集找最优就行. #include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <iomanip> #include <cstring> #include <map> #include <queue> #include <set> #i