指定m种“总面值”,对每种“总面值”,求解满足如下条件的组合以达到该“总面值”
(1) 所用邮票在n种中可以重复选取
(2) 所用邮票张数〈=4
(3) 尽量多的使用那个不同种类的邮票 Max (Stamp Types)
(4) 若有多种方案满足(3),则选取张数最小的一种方案 Min (Stamp Num)
(5) 若有多种方案满足(3)(4),则选取“最大面额”最高的一种方案。 Max(Heightest Value)
(6) 若有多种方案满足(3)(4)(5) 则输出 “tie”
思路:经典的搜索题目:超过4张的按4张处理,但看了大牛的说5张才是合适的,其次就是4层的搜索,还有就是当我们排序处理后,可以更快的处理need
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int MAXN = 30; int val[MAXN],pv,Time[MAXN],solve[6]; int flag,flag_tie; int bestSolve[6]; int max4(int s[]){ int a = max(s[1], s[2]); int b = max(s[3], s[4]); return max(a, b); } void best(int num, int type){ bestSolve[0] = num; bestSolve[5] = type; for (int i = 1; i <= 4; i++) bestSolve[i] = solve[i]; return; } void dfs(int need, int num, int type, int pre){ if (num == 5) return; if (need == 0){ if (!flag){ if (type == bestSolve[5]){ if (num == bestSolve[0]){ int Maxs = max4(solve); int Maxbs = max4(bestSolve); if (Maxs == Maxbs) flag_tie = 1; else if (Maxs > Maxbs){ flag_tie = 0; best(num, type); } } else if (num < bestSolve[0]){ flag_tie = 0; best(num, type); } } else if (type > bestSolve[5]){ flag_tie = 0; best(num, type); } } else { flag = 1; best(num, type); } return; } for (int i = pre; i < pv; i++){ if (need >= val[i]){ solve[num+1] = val[i]; if (Time[i]){ Time[i]++; dfs(need-val[i], num+1, type, i); } else { Time[i]++; dfs(need-val[i], num+1, type+1, i); } solve[num+1] = 0; Time[i]--; } else return; } return; } int main(){ while (1){ pv = 0; int type[MAXN] = {0}; int tmp; while (1){ if (scanf("%d", &tmp) == EOF) exit(0); if (tmp == 0) break; if (type[tmp] < 4){ type[tmp]++; val[pv++] = tmp; } } sort(val, val+pv); int need; while (scanf("%d", &need) != EOF && need){ flag = 0; flag_tie = 0; memset(solve, 0, sizeof(solve)); memset(bestSolve, 0, sizeof(bestSolve)); memset(Time, 0, sizeof(Time)); dfs(need, 0, 0, 0); printf("%d", need); if (bestSolve[0] == 0) printf(" ---- none\n"); else { printf(" (%d):", bestSolve[5]); if (flag_tie) printf(" tie\n"); else { sort(bestSolve+1, bestSolve+5); for (int i = 1; i <= 4; i++){ if (bestSolve[i] == 0) continue; printf(" %d", bestSolve[i]); } printf("\n"); } } } } return 0; }