zoukankan      html  css  js  c++  java
  • POJ 1018 Communication System

    题意:有n种设备,每种设备都有若干制造商,不同制造商提供设备的带宽和价格不同,现需要每种设备各一个,总带宽为这n个设备的最小带宽,总价格为这n个设备的价格之和,求最大的总带宽/总价格。

    解法:枚举+剪枝。枚举最小带宽,将所有设备进行排序,排序的优先级为b->p->id,两个剪枝:1.重复的b不需要枚举。2.当前的b无法满足让所有种类的设备都有设备的带宽大于等于b的时候不需要继续枚举。

    剪枝效果拔群……觉得是因为数据有点弱?总之32ms就过了……看到网上题解有说dp的……想了一下……没说b的范围……不知道怎么dp……orz

    代码:

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<string>
    #include<string.h>
    #include<math.h>
    #include<limits.h>
    #include<time.h>
    #include<stdlib.h>
    #include<map>
    #include<queue>
    #include<set>
    #include<stack>
    #include<vector>
    #define LL long long
    using namespace std;
    struct node
    {
        int b, p, id;
        bool operator < (const node &tmp) const
        {
            if(b == tmp.b)
            {
                if(p == tmp.p)
                    return id < tmp.id;
                return p < tmp.p;
            }
            return b < tmp.b;
        }
    }dev[10005];
    
    int main()
    {
        int T;
        scanf("%d", &T);
        while(T--)
        {
            int n;
            scanf("%d", &n);
            int cnt = 0;
            for(int i = 0; i < n; i++)
            {
                int m;
                scanf("%d", &m);
                while(m--)
                {
                    int b, p;
                    scanf("%d%d", &b, &p);
                    dev[cnt].b = b;
                    dev[cnt].p = p;
                    dev[cnt++].id = i;
                }
            }
            sort(dev, dev + cnt);
            double ans = 0.0;
            for(int i = 0; i < cnt; i++)
            {
                if(!i || dev[i].b != dev[i - 1].b)//第一个剪枝
                {
                    int now = dev[i].b;//当前枚举的b
                    int sumnum = 0, sum = 0;//已选设备种数,总价格
                    bool vis[105] = {0};//是否选过这种设备
                    int price[105];//这种设备中满足条件的最低价格
                    memset(price, 0x3f3f3f3f, sizeof price);
                    for(int j = 0; j < cnt; j++)
                    {
                        if(dev[j].b >= now)
                        {
                            if(!vis[dev[j].id])
                            {
                                vis[dev[j].id] = 1;
                                sumnum++;
                                sum += dev[j].p; 
                                price[dev[j].id] = dev[j].p;
                            }
                            else
                            {
                                if(dev[j].p < price[dev[j].id])
                                {
                                    sum -= price[dev[j].id];
                                    sum += dev[j].p;
                                    price[dev[j].id] = dev[j].p;
                                }
                            }
                        }
                    }
                    if(sumnum == n)
                        ans = max(ans, (double)now / sum);
                    else
                        break;
                }
            }
            printf("%.3lf
    ", ans);
        }
        return 0;
    }
    

      

  • 相关阅读:
    react-router JS 控制路由跳转(转载)
    vue 将值存储到vuex 报错问题
    封装GetQueryString()方法来获取URL的value值(转载)
    vue 里面的watch 选项详解
    谷歌地图api 开发 (转载)
    es6 ...展开运算符
    关于localStorage 应用总结
    js 刷新当前页面会弹出提示框怎样将这个提示框去掉
    深入浅析JavaScript的API设计原则(转载)
    jQuery mouseover与mouseenter,mouseout与mouseleave的区别
  • 原文地址:https://www.cnblogs.com/Apro/p/4857630.html
Copyright © 2011-2022 走看看