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);
	}
}


posted @ 2013-11-03 17:23  hr_whisper  阅读(123)  评论(0编辑  收藏  举报