• 蘑菇街2016笔试题 修理桌子


    # 题意

    Arthur买了一张大桌子,但是桌子腿的长度不相同,导致桌子不稳,需要修理。桌子有n条腿,第i条腿长度为(l_i),移除第i条腿的代价为(d_i)。桌子平稳的条件是超过一半的桌子腿长度达到最大长度。计算使桌子平稳的最小代价。

    输入
    第一行是一个整数:n ((1le nle 10^{5})), 表示桌腿总数。 第二行是n个整数:(l_1), (l_2), …, (l_n) ((1le l_ile10^{5})), 表示每条桌腿的长度。 第三行是n个整数:(d_1), (d_2), …, (d_n) ((1le d_ile200)), 表示移除每条桌腿的代价。

    输出
    一个整数,表示使桌子变平稳的最小代价

    样例输入

    6
    2 2 1 1 3 3
    4 3 5 5 2 1
    

    样例输出

    8
    

    # 思路

    考虑目前最长的桌腿,设其长度为lgst,数量为count,cost总和为total。针对lgst有两种可能的情况:

    • 保留长度为lgst的桌腿,此时需要使count大于桌腿数的一半;若count>n/2则不需要移除,否则需要从剩余桌腿中移除k=n-2*count+1条;选取cost最小的k个即可。
    • 移除长度为lgst的桌腿,需要将长度为lgst的桌腿,全部移除,然后从剩余桌腿的寻找稳定方案,进入递归。

    # 源码

    #include<stdio.h>
    #include<iostream>
    #include<queue>
    #include<map>
    using namespace std;
    
    typedef pair<int, int> P;
    P legs[100005];
    
    struct leg{
        int count = 0;
        int total = 0;
        vector<int> costs;
    };
    map<int, leg> table;
    
    int f(map<int, leg>::iterator it, int n, int cost){
        leg lgst = it->second;
    
        if(lgst.count > n/2) return cost;
    
        int res1 = f(--it, n-lgst.count, cost+lgst.total);
    
        ++it;
        int res2 = cost;
        int k = n - 2*lgst.count + 1;
        priority_queue<int, vector<int>, greater<int>> Q;
    
        for(map<int, leg>::iterator i = table.begin();i!=it;++i){
            leg tmp = i->second;
            for(int j=0;j<tmp.costs.size();++j){
                if(Q大专栏  蘑菇街2016笔试题 修理桌子an class="p">.size() < k) Q.push(tmp.costs[j]);
                else{
                    if(tmp.costs[j] < Q.top()){
                        Q.pop();
                        Q.push(tmp.costs[j]);
                    }
                }
            }
        }
    
        while(!Q.empty()){
            res2 += Q.top();
            Q.pop();
        }
    
        return min(res1, res2);
    }
    
    int main(){
        int n, tmp, l;
        scanf("%d", &n);
        for(int i=0;i<n;++i) scanf("%d", &legs[i].first);
        for(int i=0;i<n;++i) scanf("%d", &legs[i].second);
    
        for(int i=0;i<n;++i){
            l = legs[i].first;
            table[l].count++;
            table[l].total += legs[i].second;
            table[l].costs.push_back(legs[i].second);
    	}
    
        int res = f(--table.end(), n, 0);
        printf("%dn", res);
    
        return 0;
    }
    


    blog comments powered by Disqus

    Published

    01 April 2016

    Tags

  • 相关阅读:
    ASP.NET查看本地磁盘下的子目录和文件信息
    javascript网站导航栏
    javascript放大图片
    (转)Javascript在IE与Firefox下的差异
    C#测试代码段运行速度
    网站发布后出现的两个问题
    WebApplication与Profile购物车
    QQ在线状态接口
    mootools 14 ajax
    WRF参数配置(PartIV)
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12260904.html
Copyright © 2020-2023  润新知