USACO/Healthy Holsteins

USACO/Healthy Holsteins

Posted by dym on February 14, 2014

本文迁移自老博客,原始链接为 https://seven.blog.ustc.edu.cn/usacohealthy-holsteins/

/* 给定v个数,然后给出g组数,每一组数都有v个数组成,从g组数中选出一个集合,使得将这个集合中各个组的对应位置的数相加以后得到一组数,这组数的每一个都不能小于初始给出的那组数的对应位置的数,要求输出最小的满足要求的集合。 解法:使用位运算进行枚举,g组数对应0~2^g-1共2^g种二进制数的组合方式。枚举每种二进制组合方式,求出符合要求的解。 */

#include<iostream>
#include<algorithm>
#include<fstream>
#include<vector>
using namespace std;
#define M 1<<15

int v;
int cnt[25], ans[25];
int g , Min ,MinX;
int avl[15][1000];
vector<bool> bit;
void calbit(int val)
{
	while(val)
	{
		bit.insert(bit.end(), val%2);
		val /= 2;
	}
}
bool sta()
{
	for(int i = 0 ; i < 25 ; i++)
		if(ans[i] < cnt[i])
			return false;
	return true;
}
int main()
{
	ofstream fout ("holstein.out");
    ifstream fin ("holstein.in");
	fin>>v;
	for(int i = 0 ; i < v; i++)
		fin>>cnt[i];
	fin>>g;
	for(int i = 0 ;i < g; i++)
	{
		for(int j = 0 ;j < v; j++)
		{
			fin>>avl[i][j];
		}
	}
	Min = 10000000;
	int sum = 0;
	for(int i = 0 ; i < 1<<g ;i++)
	{
		bit.clear();
		for(int j = 0 ; j < 25; j++)
			ans[j] = 0;
		calbit(i);
		for(int j = 0 ; j < bit.size(); j++)
		{
			if(bit[j])
			{
				for(int k = 0 ; k < v;k++)
					ans[k] += avl[j][k];
			}
		}
		if(sta())
		{
			bit.clear();
			calbit(i);
			int num = 0;
			for(int k = 0 ; k < bit.size(); k++)
			{
				if(bit[k])
					num++;
			}
			if(num < Min)
			{
				Min = num;
				MinX = i;
			}
		}
	}
	vector<int> type;
	bit.clear();
	calbit(MinX);
	for(int k = 0 ; k < bit.size(); k++)
		if(bit[k])
			type.push_back(k + 1);
	fout<<Min<<" ";
	for(int i = 0 ; i < type.size() - 1; i++)
		fout<<type[i]<<" ";
	fout<<type[type.size() - 1]<<endl;
 	return 0;
}