方法一:对于每种饲料,只有两种选择:喂或者不喂。所以最多只能有2^15种方案,简单的枚举就可以了。
方法二:基于方法一的DFS,DFS树的每一层为某一种饲料喂与不喂两个分支。
方法三:我使用的是ID-DFS(迭代加深搜索),树的第k层表示喂了k种饲料。针对题目要求所喂饲料种类最少,每次DFS限定深度k,若搜索到可行解,那必定是最优解。当然,也可以用BFS,但太占空间。
/*
ID: xpli1
PROG: holstein
LANG: C++
*/
#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
#define OUT cout
#define IN cin
ofstream fout ("holstein.out");
ifstream fin ("holstein.in");
int V,G;
int vtm[26];
int fdt[16][26];
int res[26];
int path[16];
int types;
bool finded = false;
void input(){
int i,j;
IN >> V;
for(i=0; i<V; i++){
IN >> vtm[i];
}
IN >> G;
for(i=0; i<G; i++){
for(j=0; j<V; j++){
IN >> fdt[i][j];
}
}
}
bool check(){
for(int i=0; i<V; i++){
if(res[i] < vtm[i])
return false;
}
return true;
}
void add_vtm(int* v){
for(int i=0; i<V; i++)
res[i] += v[i];
}
void sub_vtm(int* v){
for(int i=0; i<V; i++)
res[i] -= v[i];
}
void dfs(int b,int k,int dep){
if(k==dep){
if(check()) {
finded = true;
}
return;
}
for(int i=b; i<G; i++){
add_vtm(fdt[i]); path[types++] = i+1;
dfs(i+1,k+1,dep);
if(finded) return;
sub_vtm(fdt[i]); path[--types] = 0;
}
}
void solve()
{
for(int dep=1; dep<=G && !finded; dep++){
memset(res,0,26*sizeof(int));
memset(path,0,16*sizeof(int));
types = 0;
dfs(0,0,dep);
}
}
void output(){
OUT << types;
for(int i=0; i<types; i++)
OUT << ' ' << path[i];
OUT << endl;
}
int main()
{
input();
solve();
output();
return 0;
}