#include <stdio.h>
#include <string.h>
int f[50000];
int c[3500],w[3500];
char color[11][11];
int max(int a,int b)
{
return a>b?a:b;
}
struct node{
int a;
char b[11];
}e[101];
int main()
{
int m,n;
while(scanf("%d%d",&m,&n)!=EOF)
{
if(m==0&&n==0)
break;
int s=0,i,j,k,t,sum,mm,p,q;
for(i=0;i<m;i++)
scanf("%s",color[i]);
for(i=0;i<n;i++)
scanf("%d%s",&e[i].a,e[i].b);
for(i=0;i<m;i++)
{
t=sum=0;
for(j=0;j<n;j++) //找出颜色相同的衣服
if(strcmp(e[j].b,color[i])==0)
{
c[t++]=e[j].a;
sum+=e[j].a;
}
memset(f,0,sizeof(f));
f[0]=1;
mm=sum/2;//分成两堆衣服来洗,两堆差越小越好,由01背包完成分组
for(p=0;p<t;p++)
{
for(q=mm;q>=c[p];q--)
if(f[q-c[p]]!=0)
f[q]=max(f[q],f[q-c[p]]+1);
}
for(p=mm;p>=0;p--)
if(f[p]!=0)
break;
s+=sum-p;
}
printf("%d\n",s);
}
return 0;
}
该题目意思是两人洗衣服,只有洗完同种颜色的衣服才能洗其他颜色的,求最少洗衣时间
思路是根据颜色分组,计算每组需要多少的时间才能洗完;
将洗衣服的总时间对半分后,由01背包可以得到最接近对半分的值,即两数中较大值最小