分析:两个人洗衣服,可以同时洗,但是只能同时洗一种颜色。
要时间最短,那么每一种颜色的清洗时间最短。
转换为,两个人洗同一种颜色的衣服,彼此之间的时间差最小。
这里也就是前面做过的01背包问题了。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int N,M;
int num[20],sum[20],dp[100010],w[20][20];
char color[20][20];
int Index(char *str)
{
for(int i=1;i<=M;i++)
if(!strcmp(str,color[i])) return i;
}
int ZeroOnePack()
{
int sumtime=0;
//第一层循环遍历所有的颜色
for(int i=1;i<=M;i++)
{
memset(dp,0,sizeof(dp));
//01背包问题
for(int j=1;j<=num[i];j++)
for(int k=sum[i]/2;k>=w[i][j];k--)
dp[k]=max(dp[k],dp[k-w[i][j]]+w[i][j]);
//计算时间总和
sumtime+=sum[i]-dp[sum[i]/2];
}
return sumtime;
}
int main()
{
char str[20];
int time;
while (scanf("%d%d",&M,&N))
{
if(N==0&&M==0) break;
for(int i=1;i<=M;i++)
scanf("%s",color[i]);
memset(num,0,sizeof(num));
memset(sum,0,sizeof(sum));
for(int i=1;i<=N;i++)
{
scanf("%d %s",&time,str);
//对数据进行预处理,按照颜色分类
int index=Index(str);
num[index]++;
sum[index]+=time;
w[index][num[index]]=time;
}
printf("%d
",ZeroOnePack());
}
return 0;
}