题目链接:http://poj.org/problem?id=3211
题意:Dearboy夫妇有一桶衣服要清洗,由于衣服颜色不同,质量也不太好,为了防止不同颜色的衣服混合清洗造成染色,所以Dearboy夫妇只能在清洗完一种颜色的衣服后再清洗另一种颜色的衣服(注意理解:如果Dearboy的老婆已经把蓝色衣服洗好了,但Dearboy洗的那一件蓝色衣服还没有清洗好,Dearboy的老婆只能等着,等Dearboy把他洗的蓝色衣服洗好了,才能一起再去洗黄色的衣服)。现有M种颜色的衣服N件,每件衣服的清洗需要的时间和颜色题目告知,问Dearboy夫妇至少需要多少时间能把衣服清洗干净。
思路:由于Dearboy夫妇只能在清洗完一种颜色的衣服后才能清洗另一种颜色的衣服,所以就要求Dearboy夫妇再清洗一种颜色的衣服时花的时间尽可能的相同。假设清洗一种颜色的衣服需要的额总时间为sumtime,将sumtime/2的背包尽可能的装满,清洗该种衣服所需要的时间则为sumtime-dp[sumtime/2](以时间长的一个为准);
代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAXM 15
#define MAXN 105
int M,N,ans;
char color[MAXM][11];
int dp[50005];
struct Close{
int time;
char col[11];
int used;
}close[MAXN];
int max(int a,int b)
{
return a>b ? a : b ;
}
int main()
{
int i,j;
while(scanf("%d%d",&M,&N) && (M!=0&&N!=0))
{
ans =0;
for(i=0;i<M;i++)
scanf("%s",color[i]);
for(i=0;i<N;i++)
{
scanf("%d %s",&close[i].time,&close[i].col);
close[i].used=0;
}
int temp[105];
for(i=0;i<M;i++)//一种颜色一种颜色的清洗
{
int num=0;
int sumtime=0;
for(j=0;j<N;j++)//求出一种颜色的衣服总共要花费多少时间清洗(sumtime)
{
if(close[j].used)
continue;
if(strcmp(color[i],close[j].col) == 0)
{
temp[num++]=close[j].time;
sumtime += close[j].time;
close[j].used = 1;
}
}
for(int l=0;l<=sumtime/2;l++)
dp[l]=0;
for(int k=0;k<num;k++)//背包sumtime/2最大装满
for(int v=sumtime/2;v>=temp[k];v--)
{
dp[v] = max(dp[v],dp[v-temp[k]]+temp[k]);
}
ans += sumtime - dp[sumtime/2];//清洗一种颜色衣服需要花费的时间
}
printf("%d\n",ans);
}
return 0;
}