zoukankan      html  css  js  c++  java
  • POJ 3211 Washing Clothes(01背包)

    POJ 3211 Washing Clothes(01背包)

    http://poj.org/problem?id=3211

    题意:

           有m (1~10)种不同颜色的衣服总共n (1~100)件。Dearboy和她的girlfriend两个人要一起洗完所有衣服,为了预防色彩混合,他们每次仅仅能同一时候洗同一种颜色的衣服,给出洗完每件衣服所需的时间time和它的颜色color,求出Dearboy和她的girlfriend最少用多少时间能洗完毕所有衣服。

    分析:

           因为每种颜色的衣服是分开洗的, 所以我们能够把全部衣服按颜色分类, 然后每次看洗一种颜色的衣服最少须要花多少时间就可以.

           如果当前第i种颜色的衣服要洗, 因为有两个人, 我们明显让这两个人洗衣服的时间尽量平均才干使得该种衣服洗的时间尽量短.

           那么这就是一个01背包问题了, 选择衣服使得一个人洗衣服的时间在<=sum/2的前提下尽量长.

           对于同一种颜色的衣服有以下01背包过程:

           令dp[i][j]=x表示仅仅在前i件衣服里面选且总时间<=j时, 能达到的最大时间为x.

           初始化: dp全为0.

           状态转移: dp[i][j] = max( dp[i-1][j] , dp[i-1][j-time[i]]+time[i])

           终于所求: 该种衣服所花时间== sum-dp[n][sum/2]. 当中sum为该种衣服所花时间总和.

     

           终于我们把每种衣服花的时间累加起来就可以得到ans.

    AC代码:

    #include<cstdio>
    #include<cstring>
    #include<map>
    #include<algorithm>
    #include<iostream>
    #include<string>
    using namespace std;
    const int maxn=100000+5;
    
    int n;               //衣服件数
    int m;               //颜色种数
    int dp[maxn];
    int num[10+5];       //num[i]=x表第i类颜色衣服有x个
    int val[10+5][100+5];//val[i][j]=x表第i类颜色的第j个衣服须要花x时间洗
    map<string,int> mp;  //颜色与编号的映射
    
    int main()
    {
        while(scanf("%d%d",&m,&n)==2)
        {
            if(n==0&&m==0) break;
            memset(num,0,sizeof(num));
    
            //读取输入,存入相应数组
            for(int i=1;i<=m;i++)
            {
                string s;
                cin>>s;
                mp[s]=i;
            }
            for(int i=1;i<=n;i++)
            {
                int x;
                string s;
                cin>>x>>s;
                int type=mp[s];
                val[type][++num[type]]=x;
            }
    
            //做最多m次01背包
            int ans=0;
            for(int k=1;k<=m;k++)
            {
                //1次01背包
                int sum=0;
                memset(dp,0,sizeof(dp));
                for(int i=1;i<=num[k];i++)
                    sum+= val[k][i];
                for(int i=1;i<=num[k];i++)
                {
                    for(int j=sum/2;j>=val[k][i];j--)
                        dp[j] = max(dp[j], dp[j-val[k][i]]+val[k][i]);
                }
                //累计结果
                ans+= sum-dp[sum/2];
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    

  • 相关阅读:
    自学传说中的php接口编写
    php数据类型
    php中的echo 与print 、var_dump 的区别
    vue 基础的一些字眼及路由
    初入 vue
    php 连接 数据库
    ExtJS获取父子、兄弟容器元素方法
    ext 的loadmask 与ajax的同步请求水火不容
    Ubuntu Server下配置UTF-8中文环境,ubuntu server zh_CN.UTF-8
    Proftpd快速搭建FTP服务器
  • 原文地址:https://www.cnblogs.com/slgkaifa/p/6848892.html
Copyright © 2011-2022 走看看