poj 3211 Washing Clothes

题意:有n(1~10)种不同颜色的衣服总共m(1~100)件,Dearboy和她的girlfriend两个人要一起洗完全部衣服,
两个人洗衣速度相同,并且已知每件衣服需要的时间<1000)。两个人可以同时洗衣。为了预防色彩混合,必须一种颜色的衣服洗完之后,两个人才能开工洗下一种颜色的衣服,问两个人洗完所有的衣服需要的最短时间。

思路:每种颜色的衣服可以分开来考虑,算出每种颜色的衣服所需要的最短时间,最后加起来即可。

然后再来考虑单一一种颜色的衣服该怎么洗,考虑到可能一个人要多洗一会儿,一个人要少洗一会儿,两个人所花的时间越接近一个人洗时总时间的一半,肯定是越好的方案,所以,用一个人洗时总时间的一半做容量,所有的衣服所花的时间做容量与价值(容量等于价值),转化成n个01背包,用01背包求出最大价值就是花时间少的那个人所用的时间了,然后用总时间减去这个花时间少的人的用时,就得到了用时多的人的用时了

#include <map>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#include <vector>
using namespace std;
#define MAX_N 11000
int n,m;
int sum[110];
int dp[MAX_N];
map<string, int> color;
int main(){
        while(~scanf("%d%d", &n, &m)){
                if(!n && !m)break;
                vector<int> v[10];
                for(int i = 0;i < n; i++){
                        string s;
                        cin >> s;
                        color[s] = i;
                }
                memset(sum, 0, sizeof(sum));
                for(int i = 0;i < m; i++){
                        int V,x;
                        string c;
                        cin >> V >> c;
                        x = color[c];
                        v[x].push_back(V);
                        sum[x] += V;
                }
                int ans = 0;
                for(int c = 0;c < n; c++){
                        int mid = (sum[c]) / 2;
                        memset(dp, 0, sizeof(dp));
                        
                        for(int i = 0; i < v[c].size(); i++){
                                for(int j = mid; j >= v[c][i]; j--){
                                        dp[j] = max(dp[j], dp[j-v[c][i]] + v[c][i]);
                                }
                        }
                        
                        ans += sum[c] - dp[mid];
                }
                printf("%d\n", ans);
        }
        return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值