#include <iostream> #include <set> #include <vector> #include <cmath> #include <cstdio> #include <cstring> #include <algorithm> #define ll long long using namespace std; const int M = 1e3 + 1; int a[M];//存储牛饲料 int b[M][M];//存储各个维生素 int c[M];//存储每次要拿的那个牛饲料的编号 int ans[M];//存储最终解 int n,m; int mi = 123456;//存储最小的使用种类,
//一开始在check函数这里想了很久,在想如何判定到底牛的维生素是否满足 int check(int x) { //对比方式是每种维生素对比 for (int i = 1; i <= n; i++) { int sum = 0;//记录每种维生素的综合 for (int j = 1; j <= c[x]; j++) { sum += b[c[j]][i];//c[x]存储的是各个编号,这里相当于对同一种需要的维生素,进行相加 } if (sum < a[i]) return 0;//如果sum<a[i] 就可以结束了,表示满足 } return 1; } inline void dfs(int t, int s) {//t代表当前是哪一种牛饲料,s代表当前已经拿了多少种 if (t > m) {//一旦已经超出了当前的牛饲料的范围,就可以结束了
//代表已经搜索完了,只有完全的搜索才能找到最优解 if (check(s)) {//判断当前解是否满足牛的维生素 if (s < mi) {//是否拿的数量更小 mi = s; for (int i = 1; i <= s; i++) { ans[i] = c[i];//更新答案序列 } } } return; }
//回溯
//这里是两种情况,对于当前的牛饲料可以采取 取和不取两种方法 c[s + 1] = t;//取,存下当前的编号 dfs(t + 1, s + 1);
//不取,因为上面取了,要把他重新变回0; c[s + 1] = 0; dfs(t + 1, s); } int main() { cin >> n; for (int i = 1; i <= n; i++) cin >> a[i]; cin >> m; for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { cin >> b[i][j]; } }
//以上都是正常存储 dfs(1,0);// cout << mi; for (int i = 1; i <= mi; i++) { cout << " " << ans[i]; } return 0; }
P1460 [USACO2.1]健康的荷斯坦奶牛 Healthy Holsteins(好题啊,终于开始用到了回溯,而且懂得了如何存数据
原文:https://www.cnblogs.com/BlogBaudelaire/p/14605316.html