• POJ1456贪心(set或者并查集区间合并)


    题意:
          给你n商品,每个商品有自己的价值还有保质期,一天最多只能卖出去一个商品,问最大收益是多少?


    思路:
          比较好想的贪心,思路是这样,每一次我们肯定拿价值最大的,至于在那天拿当然是尽可能的往后拖了,因为可以把前面的时间留给一些快过期的用,这种贪心策略很容易想到,对于实现的时候我尝试了两种方法,首先把商品按照价格从大到小排序,一个是我以前常用的set容器,他可以直接取出一个大于等于x的最小值(只要加上符号功能就是取最小的最大了),先把所有的天数都当成资源放进set里,然后对于没一个物品,如果可以买的话,那么就消耗离他保质期最近的那个没有备用的天,这样就行了,总的时间复杂度应该是O(n*log(n))的,可以接受,第二个方法我是用的并查集来处理区间合并,思路都是一样,就是在处理资源(天)的时候用并查集优化时间,比如一开始一个区间 1 2 3 4当第3天用了之后那么第三天就和第2天合并算一天了 1 2 4,就是这样每个天数的祖宗存的就是他左侧第一个没有用过的天数。这样写的话,如果用上路径压缩时间复杂度是O(n)的,比set快不少,如果不用路径压缩时间在逻辑上是O(n*n)的,但是刚刚我测试了下,跑了200+ac了。哎!这不重要。呵呵。




    并查集+贪心 79ms
    #include<stdio.h>
    #include<algorithm>


    #define N 10000 + 10


    using namespace std;


    typedef struct
    {
        int p ,d;
    }NODE;


    NODE node[N];
    int mer[N];


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


    int finds(int x)
    {
        return x == mer[x] ? x : mer[x] = finds(mer[x]);
    }


    int main ()
    {
        int n ,ans ,i ,max;
        while(~scanf("%d" ,&n))
        {
            max = 0;
            for(i = 1 ;i <= n ;i ++)
            {
                scanf("%d %d" ,&node[i].p ,&node[i].d);
                if(max < node[i].d) max = node[i].d;
            }
            for(i = 0 ;i <= max ;i ++)
            mer[i] = i;
            ans = 0;
            sort(node + 1 ,node + n + 1 ,camp);
            for(i = 1 ;i <= n ;i ++)
            {
                int x = finds(node[i].d);
                if(!x) continue;
                int y = finds(x-1);
                mer[x] = y;
                ans += node[i].p;
            }
            printf("%d " ,ans);
        }
        return 0;
    }














    set+贪心 474ms
    #include<set>
    #include<stdio.h>
    #include<algorithm>


    #define N 10000 + 10


    using namespace std;


    typedef struct
    {
        int p ,d;
    }NODE;


    NODE node[N];
    set<int>myset;


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


    int main ()
    {
        int n ,i;
        while(~scanf("%d" ,&n))
        {
            int max = 0;
            for(i = 1 ;i <= n ;i ++)
            {
                scanf("%d %d" ,&node[i].p ,&node[i].d);
                if(max < node[i].d) max = node[i].d;
            }
            myset.clear();
            myset.insert(0);
            for(i = 1 ;i <= max ;i ++)
            myset.insert(-i);
            sort(node + 1 ,node + n + 1 ,camp);
            int ans = 0;
            for(i = 1 ;i <= n ;i ++)
            {
                int x = *myset.lower_bound(-node[i].d);
                if(!x) continue;
                ans += node[i].p;
                myset.erase(x);
            }
            printf("%d " ,ans);
        }
        return 0;
    }





  • 相关阅读:
    MVC-07数据库
    Visual Web Developer 2012安裝教程
    开机启动项
    使用其他身份运行计算机(DOS命令)
    网络重置
    JavaWeb(七):EL表达式、自定义标签和JSTL
    JavaWeb(六):会话与状态管理
    JavaWeb(五):MVC案例
    JavaWeb(三):JSP
    JavaWeb(二):Servlet
  • 原文地址:https://www.cnblogs.com/csnd/p/12062514.html
Copyright © 2020-2023  润新知