POJ 3211 (分组01背包) Washing Clothes

题意:

小明有一个贤妻良母型的女朋友,他们两个一起洗衣服。

有M种颜色的N件衣服,要求洗完一种颜色的衣服才能洗另外一种颜色。

两人可以同时洗,一件衣服只能被一个人洗。

给出洗每件衣服所用的时间,求两个人洗完这些衣服所用的最短时间。

分析:

因为每种颜色是分开洗的,所以我们可以单独考虑一种颜色的衣服。

因为洗完这些衣服的总时间是固定的,所以两个人洗的时间尽可能的相等,这样洗完的时间最短。

所以将总时间的一半作为背包容量(这里总时间的奇偶性并不影响),物品的体积和价值都是洗每件衣服所用的时间,然后进行01背包。

所求答案就是总时间减去背包的最大价值。

 1 #include <iostream>
 2 #include <map>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #include <vector>
 6 #include <string>
 7 #include <cstring>
 8 using namespace std;
 9 
10 int dp[50000 + 50];
11 
12 int main()
13 {
14     freopen("in.txt", "r", stdin);
15     int M, N;
16     while(scanf("%d%d", &M, &N) == 2 && M && N)
17     {
18         map<string, vector<int> > cloth;
19         string s;
20         int l, ans = 0 ;
21         vector<string> str;
22         getchar();
23         for(int i = 0; i < M; ++i)
24         {
25             cin >> s;
26             str.push_back(s);
27         }
28         for(int i = 0; i < N; ++i)
29         {
30             cin >> l >> s;
31             cloth[s].push_back(l);
32         }
33         for(int i = 0; i < M; ++i)
34         {
35             if(cloth[str[i]].empty()) continue;
36             int n = cloth[str[i]].size();
37             int sum = 0;
38             for(int j = 0; j < n; ++j)
39                 sum += cloth[str[i]][j];
40 
41             memset(dp, 0, sizeof(dp));
42             int V = sum / 2;
43             for(int j = 0; j < n; ++j)
44                 for(int k = V; k >= cloth[str[i]][j]; --k)
45                     dp[k] = max(dp[k], dp[k-cloth[str[i]][j]] + cloth[str[i]][j]);
46 
47 
48             ans += (sum - dp[V]);
49         }
50 
51         printf("%d
", ans);
52     }
53 
54     return 0;
55 }
代码君
原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4105685.html