zoukankan      html  css  js  c++  java
  • UVA 1149 Bin Packing

    传送门

    A set of n 1-dimensional items have to be packed in identical bins. All bins have exactly the same length l and each item i has length li l. We look for a minimal number of bins q such that

       • each bin contains at most 2 items,

      • each item is packed in one of the q bins,

      • the sum of the lengths of the items packed in a bin does not exceed l.

    You are requested, given the integer values n, l, l1, . . . , ln, to compute the optimal number of bins q.

    Input

    The input begins with a single positive integer on a line by itself indicating the number of the cases following, each of them as described below. This line is followed by a blank line, and there is also a blank line between two consecutive inputs. The first line of the input file contains the number of items n (1 ≤ n ≤ 10^5 ). The second line contains one integer that corresponds to the bin length l ≤ 10000. We then have n lines containing one integer value that represents the length of the items.

    Output

    For each test case, your program has to write the minimal number of bins required to pack all items.

    The outputs of two consecutive cases will be separated by a blank line.

    Note: The sample instance and an optimal solution is shown in the figure below. Items are numbered from 1 to 10 according to the input order.

    Sample Input

    1

    10

    80

    70

    15

    30

    35

    10

    80

    20

    35

    10

    30

    Sample Output

    6

    ------------------------------------------------

    首先注意输出格式,UVA的题常常要求The outputs of two consecutive cases will be separated by a blank line.巨坑。

    Solution:

    Greedy,我的解法是从小到大枚举长度,将每个长度与另一个尽可能大的长度装在一起,若找不到就将这个长度单独装。

    Proof:

    反证法。假设存在一种的方案,其中某个装有两个物品i, j (设length(i)<=length(j))的容器b中的较短的那个物品i不是与能和它装在一起的最长物品k装在一起的,调换kj的位置,得到的是同样优的方案。所以上述贪心策略导致最优方案。

    Implementation:

    实现是用map模拟,太low了。

    #include <bits/stdc++.h>
    using namespace std;
    map<int,int> cnt;
    int main(){
        int T; scanf("%d", &T);
        for(int n, l, cs=0; T--;){
            if(cs++) puts("");
            scanf("%d%d", &n, &l);
            for(int len; n--;) scanf("%d", &len), cnt[len]++;
            int ans=0;
            for(int now; !cnt.empty();){
                now=cnt.begin()->first;
                ans++;
                cnt.begin()->second--;
                if(!cnt.begin()->second){
                    cnt.erase(now);
                }  
                if(cnt.empty()) break;
                auto it=cnt.lower_bound(l-now);
                if(it==cnt.end()) it--;
                for(;;it--){
                    if(it->first<=l-now){
                        it->second--; 
                        if(!it->second){
                            cnt.erase(it->first);
                        }
                        break;
                    }
                    if(it==cnt.begin()) break;
                }
            }
            printf("%d
    ", ans);
        }
    }

    P.S. 我本想用multiset模拟的,但后来发现multiset不支持单个删除相同元素

    multiset<int> s;
    int main(){
        s.insert(10);
        s.insert(10);
        printf("%d
    ", s.size());    //2
        s.erase(10);
        printf("%d
    ", s.size());    //0
    }
  • 相关阅读:
    linux系统权限管理拓展:特殊权限
    Linux系统对文件及目录的权限管理(chmod、chown)
    linux 用户、用户组及相关命令(useradd 、passwd、userdel 、groupadd 、groupdel、usermod 、gpasswd 、 id、su)
    Tiny4412学习杂记
    Android 使用技巧
    Tiny4412 LED 硬件服务
    Android M AudioPolicy 分析
    qt程序异常结束crashed
    source in sight 删除工程
    qt数据库sql语句使用c++中的变量
  • 原文地址:https://www.cnblogs.com/Patt/p/4842819.html
Copyright © 2011-2022 走看看