题意:
小明有一个贤妻良母型的女朋友,他们两个一起洗衣服。
有M种颜色的N件衣服,要求洗完一种颜色的衣服才能洗另外一种颜色。
两人可以同时洗,一件衣服只能被一个人洗。
给出洗每件衣服所用的时间,求两个人洗完这些衣服所用的最短时间。
分析:
因为每种颜色是分开洗的,所以我们可以单独考虑一种颜色的衣服。
因为洗完这些衣服的总时间是固定的,所以两个人洗的时间尽可能的相等,这样洗完的时间最短。
所以将总时间的一半作为背包容量(这里总时间的奇偶性并不影响),物品的体积和价值都是洗每件衣服所用的时间,然后进行01背包。
所求答案就是总时间减去背包的最大价值。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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\n", ans); 52 } 53 54 return 0; 55 }