[题意] 牛的成长需要V种维他命,每种维他命至少a[v]的量才能满足。现给出G种饲料,每种饲料含有b[G][V]的维他命的量。你的任务是算出至少需要哪几种饲料才能满足牛的成长。每种饲料只能用一次。输出饲料的数量及编号。
[思路] 枚举各种饲料的组合,每种组合都计算一下是否满足需求,如果满足,再判断一下饲料数是不是最少。如何枚举饲料的组合呢?有两种方法,一种是通过DFS深搜,一种是通过二进制枚举子集的方式进行。由于DFS还有点想不通,就研究了一下相对容易的位运算。
[代码]
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int a[30],b[20][30],num[30];
bool date[30];
int V,G;
bool check()
{
for(int i=0;i<V;i++)
if(num[i]<a[i])
return false;
return true;
}
int main()
{
int sum=0,SUM=30,n;
cin>>V;
for(int i=0;i<V;i++)
cin>>a[i];
cin>>G;
for(int i=0;i<G;i++)
for(int j=0;j<V;j++)
cin>>b[i][j];
int s=1;
for(inti=1;i<=(1<<G);i++){
memset(num,0,sizeof(num));
s=1;
sum=0;
for(int j=0;j<G;j++){
if(i&s){
sum++;
for(intii=0;ii<V;ii++)
num[ii]+=b[j][ii];
}
s<<=1;
}
if(check()){
if(sum<SUM){
SUM=sum;
n=i;
}
}
}
cout<<SUM<<' ';
s=1;
for(int j=0;j<G;j++){
if(n&s){
SUM--;
if(!SUM)
cout<<j+1<<endl;
elsecout<<j+1<<' ';
}
s<<=1;
}
}