POJ 3211 Washing Clothes 0-1背包

时间:2023-03-09 16:22:12
POJ 3211 Washing Clothes 0-1背包

题目大意:

xxx很懒,但他有个漂亮又勤奋的女友 (尼玛能不能不刺激我,刚看到这题的时候发现自己的衣服没洗!!!) 可以帮他洗衣服。

洗衣服的时候要求不同的颜色的衣服不能同时洗。一人洗一件的话,问最短的时间。

对每个颜色的衣服进行划分,最后求和,就转化为若干个0-1背包问题。

对于每种颜色:因为两个人同时洗,但不能一起洗一件,故时间必为长的那个。

所以若时间接近一半,则为最优解。这样背包的容量为sum[i] /2 ,sum[i]为该组颜色衣服时间和

f[k]=max( f[k],f[k-a[i][j]]+a[i][j] ); 



因为现在是不超过t/2时间的,故等下的每组的答案是sum[i] -f[ sum[i] / 2 ]

PS:

别忘了每组都要初始化一次f函数,QAQ傻了,没初始化结果一直WA

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=10000+10;
char kind[11][15],temp[15];
int a[11][105],num[11],sum[11];
int N,M,t;
int f[MAXN]; int index(char *s)
{
int i;
for( i=0;i<M;i++)
if(strcmp(s,kind[i])==0)
return i;
} int main()
{
while(scanf("%d%d",&M,&N),M||N)
{
int ans=0;
memset(kind,0,sizeof(kind));
memset(a,0,sizeof(a));
memset(num,0,sizeof(num));
memset(sum,0,sizeof(sum)); for(int i=0;i<M;i++)
scanf("%s",kind[i]); for(int i=0;i<N;i++)
{
scanf("%d%s",&t,temp);
int id=index(temp);
a[id][ ++num[id] ]=t;
sum[id]+=t;
} for(int i=0;i<M;i++)
{
memset(f,0,sizeof(f));
for(int j=1;j<=num[i];j++)
{
for(int k=sum[i]/2;k>=a[i][j];k--)
{
f[k]=max(f[k],f[k-a[i][j]]+a[i][j] );
}
}
ans =ans+ sum[i] -f[ sum[i] / 2 ];
} printf("%d\n",ans);
}
}