Welcome

首页 / 软件开发 / 数据结构与算法 / 算法:poj 3211 Washing Clothes(01背包)

算法:poj 3211 Washing Clothes(01背包)2014-01-10 csdn shuangde800题目大意:

Dearboy和他的女朋友一起洗m件衣服,共有n总颜色(每件衣服只有一种颜色)。 为 了放置不同颜色互染,每次只能洗一种颜色的衣服,在这件衣服洗完之前不能洗另外一种衣服。 Dearboy和 他女朋友可以同时一起洗衣服,但是不能同时洗同一件衣服,也不能同时洗不同种颜色的衣服。

一 只每件衣服所需时间,问最少花费多少时间可以全部洗完。

分析:

首先可以很直观的判定, 一定是把一种颜色的所有衣服都洗完再接着洗另外一种颜色的衣服,洗每种颜色所有衣服的总时间是分开独 立的。

关键是洗同一种颜色的衣服时,Dearboy和他的女朋友怎样分配任务才可以最快完成?  最理想的情况时,两人各洗一半的时间。 所以,我们要尽量分配给两人的任务时长接近总时长的一 半,最后洗完单种颜色的衣服所花的时间,取决于时长较大的那个。

很明显的可以用01背包来做, 每件衣服的时间是容量也是价值,总时间的一半为背包的容量,然后01背包。

代码:

#include<iostream>#include<queue>#include<cstdio>#include<cstring>#include<cmath>#include<map>#include<string>#define MP make_pair#define SQ(x) ((x)*(x)) using namespace std;typedef long long int64; const int MAXN = 110;const int INF = 0x3f3f3f3f;int n, m;int h[25];int w[12][MAXN], sum[12], num[12];int f[MAXN*1000]; int main(){char color[12];int t;while(~scanf("%d%d", &n, &m) && n+m){ map<string, int>mp;for(int i=0; i<n; ++i){scanf("%s",color);mp[color] = i;} for(int i=0; i<=n; ++i) sum[i] = num[i] = 0; for(int i=0; i<m; ++i){scanf("%d%s", &t, color);int pt=mp[color];w[pt][num[pt]++] = t;sum[pt] += t;}int ans = 0; for(int k=0; k<n; ++k){ for(int i=0; i<=sum[k]/2; ++i) f[i] = 0;for(int i=0; i<num[k]; ++i){for(int v=(sum[k]>>1); v>=w[k][i]; --v)f[v] = max(f[v], f[v-w[k][i]]+w[k][i]);}ans += sum[k]-f[sum[k]>>1]; }printf("%d
",ans); }return 0;}