Burch & Kolstad
Farmer John prides himself on having the healthiest dairy cowsin the world. He knows the vitamin content for one scoop of eachfeed type and the minimum daily vitamin requirement for the cows.Help Farmer John feed his cows so they stay healthy while minimizingthe number of scoops that a cow is fed.
Given the daily requirements of each kind of vitamin that a cowneeds, identify the smallest combination of scoops of feed a cowcan be fed in order to meet at least the minimum vitamin requirements.
Vitamins are measured in integer units. Cows can be fed at mostone scoop of any feed type. It is guaranteed that a solution existsfor all contest input data.
PROGRAM NAME: holstein
INPUT FORMAT
Line 1: | integer V (1 <= V <= 25), the number of types of vitamins |
Line 2: | V integers (1 <= each one <= 1000), the minimum requirement for each of the V vitamins that a cow requires each day |
Line 3: | integer G (1 <= G <= 15), the number of types of feeds available |
Lines 4..G+3: | V integers (0 <= each one <= 1000), the amount of each vitamin that one scoop of this feed contains. The first line of these G lines describes feed #1; the second line describes feed #2; and so on. |
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
The output is a single line of output that contains:
- the minimum number of scoops a cow must eat, followed by:
- a SORTED list (from smallest to largest) of the feed types the cow is given
SAMPLE OUTPUT (file holstein.out)
2 1 3
————————————————————宅的分割线————————————————————
前言:虽然知道是记忆化搜索,但是也许是太久没有复习所以忘记的缘故写不出来。只好滚过去研究题解。
思路:记忆化搜索的要素是状态和边界。对于每个饲料,只有用和不用两种选择,所以这是状态1,而已经用了多少饲料正是状态2,也是要求的解。边界条件,是所有的饲料都决策过了。这个时候检测答案是否合法(各营养值都达标),然后根据使用饲料是否更少来更新答案。
至于没有达到边界的操作,另开一个数组记录当前营养值,先加上使用当前饲料的营养值,dfs进去,然后减去(恢复状态变化),再dfs进去就行了。
代码如下:
/*
ID: j.sure.1
PROG: holstein
LANG: C++
*/
/****************************************/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <string>
#include <iostream>
using namespace std;
/****************************************/
const int N = 30;
int need[N], feed[N][N], now[N], ans[N], cur_ans[N];
int vita, have, mini = 2e9;
void dfs(int cur, int use)
{
if(cur == have) {
for(int i = 0; i < vita; i++) {
if(now[i] < need[i])
return;
}
if(use < mini) {
mini = use;
for(int i = 0; i < mini; i++) {
ans[i] = cur_ans[i];
}
}
return ;
}
for(int i = 0; i < vita; i++) {
now[i] += feed[cur][i];
}
cur_ans[use] = cur+1;
dfs(cur+1, use+1);
for(int i = 0; i < vita; i++) {
now[i] -= feed[cur][i];
}
dfs(cur+1, use);//不使用该饲料,进入下一个饲料
}
int main()
{
freopen("holstein.in", "r", stdin);
freopen("holstein.out", "w", stdout);
scanf("%d", &vita);
for(int i = 0; i < vita; i++) {
scanf("%d", &need[i]);
}
scanf("%d", &have);
for(int i = 0; i < have; i++) {
for(int j = 0; j < vita; j++) {
scanf("%d", &feed[i][j]);
}
}
memset(now, 0, sizeof(now));
dfs(0, 0);
printf("%d", mini);
for(int i = 0; i < mini; i++) {
printf(" %d", ans[i]);
}
printf("\n");
return 0;
}