将问题转换成物品无线的背包问题,下面是代码:
// UVa 242 #include <cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std; const int maxn = 10 + 5; const int maxm = 1000 + 5; // 1000 = 100 * 10 struct Item { vector<int> stamp; int Max_val; bool operator < (const Item& rhs) const { if (Max_val != rhs.Max_val) return Max_val > rhs.Max_val; if (stamp.size() != rhs.stamp.size()) return stamp.size() < rhs.stamp.size(); for (int i = stamp.size()-1; i >= 0; --i) if (stamp[i] != rhs.stamp[i]) return stamp[i] < rhs.stamp[i]; return false; } } item[maxn]; int s, n, d[maxm]; void get_Max_val(vector<int>& v, int p) { memset(d, 0x3f, sizeof(d)); item[p].Max_val = 0; d[0] = 0; for (int i = 1; ; ++i) { for (int j = 0; j < v.size(); ++j) if (i >= v[j]) d[i] = min(d[i], d[i-v[j]]+1); if (d[i] <= s) item[p].Max_val = i; else break; } } void print_ans() { printf("max coverage =%4d :", item[0].Max_val); for (int i = 0; i < item[0].stamp.size(); ++i) printf("%3d", item[0].stamp[i]); printf("\n"); } int main() { while (scanf("%d", &s) == 1 && s) { scanf("%d", &n); for (int i = 0; i < n; ++i) { int m, val; scanf("%d", &m); item[i].stamp.clear(); for (int j = 0; j < m; ++j) { scanf("%d", &val); item[i].stamp.push_back(val); } get_Max_val(item[i].stamp, i); } sort(item, item+n); print_ans(); } return 0; }