zoukankan      html  css  js  c++  java
  • CodeForces 557C Arthur and Table STL的使用

    题意:一个桌子有n条腿,每条腿有一定的长度l,和砍下的花费w,现在规定,桌子稳的条件是长度最长的腿(可多个)的数量大于长度小于它的桌子腿数量,且不存在比他还长的桌子腿,求让桌子腿稳定的最小的花费

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <vector>
    #include <queue>
    #include <map>
    #include <algorithm>
    #include <set>
    using namespace std;
    typedef long long ll;
    const double eps = 1e-10;
    const int inf = 0x3f3f3f3f;
    const double pi=acos(-1);
    const int mod=100000000;
    int max(int a,int b)
    {return a>b?a:b;};
    int min(int a,int b)
    {return a<b?a:b;};
    
    const int maxl=100000;
    struct node{
       int l,w;
    }ne[100005];
    
    bool cmp(node a,node b)
    {
        return a.l<b.l;
    }
    
    vector<int> numw[205];
    int n,num[maxl+5],total[maxl+5];
    
    void solve()
    {
        int ans=inf;
        for(int i=1;i<=maxl;i++)
          if(num[i])
          {
            int temp=total[i+1],k=num[i]-num[i+1];
            int cnt=num[1]-num[i]-(k-1);
            if(cnt>0)
            {
             for(int j=1;j<=200;j++)
                if(numw[j].size())
                {
                    //printf(":2
    ");
                    if(cnt<=0) break;
                    int p=lower_bound(numw[j].begin(),numw[j].end(),i)-numw[j].begin();//花费为j的桌子腿中长度>=i的个数
                    temp+=min(p,cnt)*j;
                    cnt-=p;
                   // printf(":3
    ");
                }
            }
            ans=min(ans,temp);
            }
        printf("%d
    ",ans);
    }
    
    void init()
    {
        memset(total,0,sizeof(total));
        memset(num,0,sizeof(num));
        for(int i=0;i<=200;i++)
            numw[i].clear();
    }
    
    void input()
    {
        init();
       //printf("||5
    ");
        for(int i=1;i<=n;i++)
           {
             scanf("%d",&ne[i].l);
             num[ne[i].l]++;
           }
        for(int i=1;i<=n;i++)
           {
               scanf("%d",&ne[i].w);
               numw[ne[i].w].push_back(ne[i].l);
           }
        //printf("|||6
    ");
        sort(ne+1,ne+n+1,cmp);
        for(int i=1;i<=n;)
        {
            int p=i;
            while(ne[p].l==ne[i].l&&i<=n)
                {
                    total[ne[p].l]+=ne[i].w;
                    i++;
                }
        }
        for(int i=maxl;i>=1;i--)
             {
                 total[i]+=total[i+1];
                 num[i]+=num[i+1];
             }//total数组统计砍下长度>=i的所有桌子腿的总花费
    //num数组记录长度>=i的桌子腿的个数
    for(int i=1;i<=200;i++) if(numw[i].size()) sort(numw[i].begin(),numw[i].end()); } int main() { while(~scanf("%d",&n)) { input(); solve(); } return 0; }

    核心思路:先暴力枚举最长的桌子腿腿长(1e5),然后再按花费(<=200)进行从小到大的贪心选取

    ,每次在花费为w上进行贪心时,找出小于当前枚举的长度的桌子腿个数,本题的实现是个大难题

    错因分析:本来想用优先队列来维护权花费为w的长度序列的,实现本代码中vector的操作,但是优先队列

    没有迭代器,不支持begin()这个操作,也就是priority_queue<node> a[100],a[1]就是代表一个优先队列,没有a[1].begin()这个操作,事实上优先队列只有pop(),top(),和insert(),这三个操作,其实就是个堆。

  • 相关阅读:
    微博那点事(2)
    微博那点事(1)
    Netty断线重连
    高效沟通技巧
    Latex 公式在线可视化编辑器
    RPC框架原理与实现
    Java 静态代理与动态代理
    程序员主管之路(1)
    MarkDown 常用语法教程
    Solr vs. Elasticsearch谁是开源搜索引擎王者
  • 原文地址:https://www.cnblogs.com/smilesundream/p/5273130.html
Copyright © 2011-2022 走看看