1 条题解
-
0
//求必须的最小饲料种数,从idx种开始往后遍历 //没找到一个可行的方案,对比一下是否种类数最小,最小就存起来 //最后输出ans,ansqueue[] #include <iostream> #include <cstring> #include <fstream> using namespace std; const int N = 30, M = 25; int vita[N], vitatmp[N]; //vitatmp存当前的维生素的量,用来判断是否够用 int g[M][N]; int vitaqueue[M]; int ansqueue[M]; //用来存放饲料的序号 int ans = 0x3f; //记录最小方案的维生素方案种数 int vis[M]; //是否使用过 int n, m; int idx; bool check() { for (int i = 1; i <= n; i++) if (vitatmp[i] < vita[i]) return false; return true; } void dfs() { //for (int i = 1; i <= idx; i++) printf("%d ", ansqueue[i]); //puts(""); //这个地方不进行剪枝,数据也能过 //if (idx > ans || idx > m) return; if (check()) { //vitatmp够用,但是饲料种数不是最小,就剪枝 if (idx >= ans) return ; //暴力搜索,会不断刷新出来优化的方案,存起来 ans = idx; for (int i = 1; i <= ans; i++) ansqueue[i] = vitaqueue[i]; //for (int i = 1; i <= ans; i++) printf("%d ", ansqueue[i]); //puts(""); } //如果当前vitatmp还不够用,需要继续去找 for (int i = vitaqueue[idx]; i <= m; i++) { if (i >= 1 && !vis[i]) { vis[i] = 1; vitaqueue[++idx] = i; for (int j = 1; j <= n; j++) vitatmp[j] += g[i][j]; dfs(); for (int j = 1; j <= n; j++) vitatmp[j] -= g[i][j]; //j<=n 打成i<=n,调试3小时,溺, bus error 10 idx--; vis[i] = 0; } } return ; } int main() { //freopen("P1460_2.in", "r", stdin); cin >> n; for (int i = 1; i <= n; i++) cin >> vita[i]; //vita[]存所需vita标准值 cin >> m; for (int i = 1; i <= m; i++) for (int j = 1; j <= n; j++) cin >> g[i][j]; dfs(); printf("%d ", ans); for (int i = 1; i <= ans; i++) printf("%d ", ansqueue[i]); puts(""); return 0; }总结一下:
dfs真香
很多题解用的类似DP,那个解法很好,集合思想
如果数据很大的时候,可以用二进制进行优化,那就高级了
MacOS下,第一次遇到 Bus error 10的错误,知道是栈溢出,查了3小时也没整明白。最后用printf大法,打断点看执行过程,一下就揪出了问题(for循环里面i打成了j,溺)
- 1
信息
- ID
- 1003
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 9
- 标签
- 递交数
- 8
- 已通过
- 8
- 上传者