zoukankan      html  css  js  c++  java
  • POJ1018贪心(多路归并的想法)

    题意:
         有n个服务器,每个服务器都要安装网线(必须也只能安装一个),然后每个服务器都有mi种选择网线的方式,每种方式两个参数,一个是速度b,另一个是价钱p,然后让你找到一个最大的比值 minb/sump,就是所有的选择中最小的那个速度,必上话的钱的总和。


    思路: 
          这个题目按照讨论组里面的说法估计做法很多,不管了,说下我自己的做法吧,我的做法有点像操作系统里面那个多路归并(如果没记错是叫这个,做题的时候突然想到这个方式,试了下,还真行),具体是这样,枚举最小的b,也就是最小的那个带宽,对于每个服务器,我们可以先把他所有的可选择项都按照带宽从小到大排序,排序后再倒着预处理得到每个选项后面中最小的那个花费,全部这样处理完之后就得到了一个二维的表,然后我们开始枚举,每个表都是根据带宽从小到大排序的,这样所有中最小的那个肯定就是某一个的第一项,我们O(n)的时间找到第一项,以这一项的带宽为最小带宽,花费是当前这个选项的花费,其他的就选最小的花费,然后删除找到的这一项,就这样一直找到头一个服务器的选项全都用完了位置,还有就是删除项的时候可以开一个一维数组,记录当前这个服务器已经用到第几项了,删除第i个服务器的当前项,直接mk[i]++就行了,16msAC,总的时间复杂度最坏应该是 O(n*n*n) 1000000吧。感觉思路有点瞎扯了,呵呵,题目不难,瞎扯就瞎扯吧,好就说这些。


    #include<stdio.h>
    #include<string.h>
    #include<algorithm>


    #define N 100 + 10
    #define INF 1000000000


    using namespace std;


    typedef struct
    {
        int b ,p ,minp;
    }NODE;


    NODE node[N][N];
    int now[N] ,num[N];


    bool camp(NODE a ,NODE b)
    {
        return a.b < b.b;
    }


    int main ()
    {
        int t ,i ,j ,n ,tmp ,sn;
        scanf("%d" ,&t);
        while(t--)
        {
            scanf("%d" ,&n);
            for(i = 1 ,sn = 0 ;i <= n ;i ++)
            {
                scanf("%d" ,&num[i]);
                sn += num[i];
                for(j = 1 ;j <= num[i] ;j ++)
                scanf("%d %d" ,&node[i][j].b ,&node[i][j].p);
                sort(node[i] + 1 ,node[i] + num[i] + 1 ,camp);
                for(j = num[i] ;j >= 1 ;j --)
                {
                    if(j == num[i] || tmp > node[i][j].p)
                    tmp = node[i][j].p;
                    node[i][j].minp = tmp;
                }
                now[i] = 1;
            }
            double Ans = 0;
            int nowb ,nowp;
            while(sn--)
            {
                nowb = INF;
                nowp = 0;
                int mkbreak = 0;
                for(i = 1 ;i <= n ;i ++)
                {
                    if(now[i] > num[i]) mkbreak = 1;
                    if(nowb > node[i][now[i]].b)
                    nowb = node[i][now[i]].b;
                }
                if(mkbreak) break;
                int mk = 0;
                for(i = 1 ;i <= n ;i ++)
                {
                    //if(now[i] > num[i]) continue;
                    if(!mk && nowb == node[i][now[i]].b)
                    {
                        mk = 1;
                        nowp += node[i][now[i]].p;
                        now[i] ++;
                    }
                    else nowp += node[i][now[i]].minp;
                }
                if(Ans < nowb * 1.0 / nowp)
                Ans = nowb * 1.0 / nowp;
            }
            printf("%.3lf " ,Ans);
        }
        return 0;
    }



  • 相关阅读:
    Android 动画-alpha(渐变透明度动画效果)
    Memento(备忘录)
    Mediator(中介者)
    Iterator(迭代器)
    Command(命令)
    Chain of Responsibility(责任链)
    Template Method(模板方法)
    Interpreter(解释器)
    Proxy(代理)
    Flyweight(享元)
  • 原文地址:https://www.cnblogs.com/csnd/p/12062492.html
Copyright © 2011-2022 走看看