PKU--3211 Washing Clothes(01背包)

题目http://poj.org/problem?id=3211
分析:两个人洗衣服,可以同时洗,但是只能同时洗一种颜色。
要时间最短,那么每一种颜色的清洗时间最短。
转换为,两个人洗同一种颜色的衣服,彼此之间的时间差最小。
这里也就是前面做过的01背包问题了。
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

int N,M;
int num[20],sum[20],dp[100010],w[20][20];
char color[20][20];


int Index(char *str)
{
    for(int i=1;i<=M;i++)
        if(!strcmp(str,color[i])) return i;
}

int ZeroOnePack()
{
    int sumtime=0;
    //第一层循环遍历所有的颜色
    for(int i=1;i<=M;i++)
    {
        memset(dp,0,sizeof(dp));
        //01背包问题
        for(int j=1;j<=num[i];j++)
            for(int k=sum[i]/2;k>=w[i][j];k--)
                dp[k]=max(dp[k],dp[k-w[i][j]]+w[i][j]);
               
    //计算时间总和
        sumtime+=sum[i]-dp[sum[i]/2];
    }
    return sumtime;
}


int main()
{
    char str[20];
    int time;
    while (scanf("%d%d",&M,&N))
    {
    if(N==0&&M==0) break;
        for(int i=1;i<=M;i++)
            scanf("%s",color[i]);

        memset(num,0,sizeof(num));
        memset(sum,0,sizeof(sum));

        for(int i=1;i<=N;i++)
        {
            scanf("%d %s",&time,str);
            //对数据进行预处理,按照颜色分类
            int index=Index(str);
            num[index]++;
            sum[index]+=time;
            w[index][num[index]]=time;
        }

        printf("%d ",ZeroOnePack());
    }
    return 0;
}





原文地址:https://www.cnblogs.com/gt123/p/3467347.html