题目描述
农民JOHN以拥有世界上最健康的奶牛为傲。他知道每种饲料中所包含的牛所需的最低的维他命量是多少。请你帮助农夫喂养他的牛,以保持它们的健康,使喂给牛的饲料的种数最少。
给出牛所需的最低的维他命量,输出喂给牛需要哪些种类的饲料,且所需的饲料剂量最少。
维他命量以整数表示,每种饲料最多只能对牛使用一次,数据保证存在解。
输入输出格式
输入格式:
第1行:一个整数V(1<=V<=25),表示需要的维他命的种类数。
第2行:V个整数(1<=每个数<=1000),表示牛每天需要的每种维他命的最小量。
第3行:一个整数G(1<=G<=15),表示可用来喂牛的饲料的种数。
下面G行,第n行表示编号为n饲料包含的各种维他命的量的多少。
输出格式:
输出文件只有一行,包括
牛必需的最小的饲料种数P
后面有P个数,表示所选择的饲料编号(按从小到大排列)。
如果有多个解,输出饲料序号最小的(即字典序最小)。
输入输出样例
输入样例#1:
4 100 200 300 400 3 50 50 50 50 200 300 200 300 900 150 389 399
输出样例#1:
2 1 3
说明
USACO 2.1
翻译来自NOCOW
【分析】
搜索+剪枝。
有两个点一直迷之出错,最后发现是数组大小开反了...
【代码】
1 #include <bits/stdc++.h> 2 #define inf 0x7fffffff 3 using namespace std; 4 5 int v, g, c[30], f[20][30], ans[20], t[30]; 6 bool vis[20]; 7 8 bool check() { 9 for (int i=1;i<=v;++i) 10 if (t[i]<c[i]) 11 return false; 12 return true; 13 } 14 15 void dfs(int k, int last) { 16 if (k>=ans[0]) 17 return; 18 if (check()) { 19 ans[0]=0; 20 for (int i=1;i<=g;++i) 21 if (vis[i]) 22 ans[++ans[0]]=i; 23 return; 24 } 25 for (int i=last+1;i<=g;++i) { 26 if (!vis[i]) { 27 vis[i]=true; 28 for (int j=1;j<=v;++j) t[j]+=f[i][j]; 29 dfs(k+1, i); 30 for (int j=1;j<=v;++j) t[j]-=f[i][j]; 31 vis[i]=false; 32 } 33 } 34 } 35 36 int main() { 37 ans[0]=inf; 38 cin >> v; 39 for (int i=1;i<=v;++i) scanf("%d", &c[i]); 40 cin >> g; 41 for (int i=1;i<=g;++i) 42 for (int j=1;j<=v;++j) scanf("%d", &f[i][j]); 43 memset(t, 0, sizeof(t)); 44 dfs(0, 0); 45 cout << ans[0]; 46 for (int i=1;i<=ans[0];++i) cout << " " << ans[i]; 47 }
时间: 2024-11-06 19:13:43