poj 3211 Washing Clothes 背包
这题做得相当顺利,1A
题意是求夫妇两人洗完衣服用的最小时间。先按衣颜色分类,对于每种颜色的衣服,最优解是都平分即V/2,背包容量为洗衣服的花费,用01背包来标记是否可以通过组合组成某个容量。若不能平均分,就从V/2开始搜索,最接近V/2的较大值就为两人洗完每种颜色衣服的最短时间,把各种颜色衣服的解加起来即为答案
#include <iostream> #include <map> #include <string> #include <vector> #include <cstring> using namespace std; const int MAX = 100*1001; const int N = 101; bool isvisit[MAX]; int cap[N]; map<string, int> cloth; vector<int> group[N]; int m, n; int find(int color) { int size = group[color].size(); int sum = 0; memset(isvisit, false, sizeof(isvisit)); for (int i = 0; i < size; i++) sum += cap[ group[color][i] ]; isvisit[0] = true; for (int i = 0; i < size; i++) for (int v = sum; v >= cap[ group[color][i] ]; v--) if (!isvisit[v] && isvisit[v - cap[ group[color][i] ] ]) isvisit[v] = true; int v = sum; if (sum % 2 == 0) sum /= 2; else sum = sum/2+1; for (int i = 0; i+sum <= v; i++) if (isvisit[sum+i]) return sum+i; } int main() { string s; while (cin >> m >> n && m||n) { cloth.clear(); for (int i = 0; i < m; i++) { cin >> s; cloth[s] = i; group[i].clear(); } for (int i = 1; i <= n; i++) { cin >> cap[i] >> s; group[ cloth[s] ].push_back(i); } int ans = 0; for (int i = 0; i < m; i++) ans += find(i); cout << ans << endl; } return 0; }