码迷,mamicode.com
首页 > 其他好文 > 详细

2.1.4 Healthy Holsteins 健康的好斯坦奶牛

时间:2015-01-23 23:04:57      阅读:284      评论:0      收藏:0      [点我收藏+]

标签:healthy holsteins   c++   题解   usaco   

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;
}


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



2.1.4 Healthy Holsteins 健康的好斯坦奶牛

标签:healthy holsteins   c++   题解   usaco   

原文地址:http://blog.csdn.net/finded/article/details/43063983

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!