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); } }
新 blog : www.hrwhisper.me