题目很有意思,很好理解,挺好的一道背包问题
只需将每种颜色分别用01背包方法求出最接近于该颜色时间总和一半的时间,然后用该颜色时间总和减去它。
最后将每种颜色所花费的时间累加即可。
#include<iostream>
using namespace std;
#include<cstdio>
#include<cstring>
struct cclothes{
int sum; ///计数,该颜色的衣服的总和
int n; ///计数,该颜色的衣服有几件
int s[105]; ///标记,完成每一个piece所花费的时间 开始数组开小了只开到了15 1W
char color[12]; ///衣服的颜色名
}clothes[15];
int dp[10005];
int main()
{
int i,j,m,n;
while(scanf("%d%d",&m,&n))
{
if(m==0 && n==0)
return 0;
for(i=1;i<=m;i++)
{
cin>>clothes[i].color;
clothes[i].n=1;
clothes[i].sum=0;
}
int time;
char skirt[12];
for(i=1;i<=n;i++)
{
cin>>time>>skirt;
for(j=1;j<=m;j++)
{
if(strcmp(skirt,clothes[j].color)==0)
{
clothes[j].s[clothes[j].n++]=time;
clothes[j].sum+=time;
}
}
}
int ans=0,v,k;
for(i=1;i<=m;i++)
{
memset(dp,0,sizeof(dp));
///0/1背包
for(j=1;j<=clothes[i].n-1;j++)
{
for(v=clothes[i].sum/2;v>=clothes[i].s[j];v--)
{
dp[v]=max(dp[v],dp[v-clothes[i].s[j]]+clothes[i].s[j]);
}
}
ans+=clothes[i].sum-dp[clothes[i].sum/2]; ///进行累加
}
printf("%d\n",ans);
}
return 0;
}