这题想通了很简单,不过难的就是想的过程,我想了一个上午,由于没有去重超时了,后来还是同学点拨才过的,用数组模拟组合,当数组的某个元素a[i]=1时表示选取第(i-1)(或者i,这里看数组的下标从0开始还是从1开始)个,a[i] = 0表示不选第(i-1)个。然后再在符合情况的组合中选取元素最少的(也就是步数最少的)。
官方的报告和这一样的思路
官方
 1Since there are only 15 feeds, and for each feed we can either give zero or one scopes of it, there are 215 possible `feed mixtures' the cows can be fed, which is only 32,768. Therefore, try all combinations and pick which of the legal combinations uses the least number of feeds. 
 2
 3#include <stdio.h>
 4#include <assert.h>
 5
 6#define MAXV 25
 7#define MAXF 15
 8
 9int req[MAXV]; /**//* the vitamin requirements */
10int numv; /**//* number of vitamins */
11
12int feeds[MAXF][MAXV]; /**//* the vitamin within each feed */
13int numf; /**//* number of feeds */
14
15int best; /**//* the minimum number of feeds to use found thus far */
16int bestf[MAXF]; /**//* the set */
17
18int curf[MAXF]; /**//* the current set of feeds being considered */
19
20void find_feed(int fcnt, int fid)
21 /**//* fcnt is the number of feeds in the current mixture,
22      fid is the identifier of the first feed to try adding (last feed + 1) */

23  int lv;
24
25  /**//* check if the requirement has been met */
26  for (lv = 0; lv < numv; lv++)
27    if (req[lv] > 0break
28  if (lv >= numv)
29   /**//* all the requirements are met */
30    /**//* we know this is better, since we wouldn't have checked it otherwise
31       (see below) */

32    best = fcnt;
33    for (lv = 0; lv < best; lv++)
34      bestf[lv] = curf[lv];
35    return;
36   }

37
38  while (fid < numf && fcnt+1 < best)
39   /**//* try adding each feed to the mixture */
40     /**//* the fcnt+1 < best ensures that we stop if there's no hope
41    in finding a better solution than one found already */

42
43    /**//* add the vitamins from this feed */
44    for (lv = 0; lv < numv; lv++)
45      req[lv] -= feeds[fid][lv]; 
46    curf[fcnt] = fid; /**//* put it in the list */
47
48    find_feed(fcnt+1, fid+1); 
49
50    /**//* undo adding the vitamins */
51    for (lv = 0; lv < numv; lv++)
52      req[lv] += feeds[fid][lv];
53
54    /**//* next feed */
55    fid++;
56   }

57 }

58
59int main(void
60 {
61  FILE *fin, *fout;
62  int lv, lv2;
63
64  fin = fopen("holstein.in""r");
65  fout = fopen("holstein.out""w");
66  assert(fin);
67  assert(fout);
68
69  fscanf (fin, "%d"&numv);
70  for (lv = 0; lv < numv; lv++)
71    fscanf (fin, "%d"&req[lv]);
72  fscanf (fin, "%d"&numf);
73  for (lv = 0; lv < numf; lv++)
74    for (lv2 = 0; lv2 < numv; lv2++)
75      fscanf (fin, "%d"&feeds[lv][lv2]);
76
77  best = numf+1;
78  find_feed(00);
79
80  fprintf (fout, "%i", best);
81  for (lv = 0; lv < best; lv++
82    fprintf (fout, " %i", bestf[lv]+1);
83  fprintf (fout, "\n");
84  return 0;
85 }

86
87