HDU4846Task treap + 贪心

题意:给你 n台机器,m个任务,机器有两个属性值  一天最多工作时间X,机器等级 Y  ,任务有两个属性值   需要机器的工作时间X,需要机器的工作等级 Y ,每台机器一天只能做一个任务,每做一个任务可以获得  500×Y + 2×X 的价值,问你在完成最多任务的情况下最多价值为多少。

解题思路:

首先是贪心,可以知道Y的影响比X大的多。所以对任务Y从大到大排序,然后在找最接近的机器,(从大到小填一定是最优的。)

解题代码:

  1 // File Name: 1004.cpp
  2 // Author: darkdream
  3 // Created Time: 2014年07月29日 星期二 09时51分07秒
  4
  5 #include<vector>
  6 #include<list>
  7 #include<map>
  8 #include<set>
  9 #include<deque>
 10 #include<stack>
 11 #include<bitset>
 12 #include<algorithm>
 13 #include<functional>
 14 #include<numeric>
 15 #include<utility>
 16 #include<sstream>
 17 #include<iostream>
 18 #include<iomanip>
 19 #include<cstdio>
 20 #include<cmath>
 21 #include<cstdlib>
 22 #include<cstring>
 23 #include<ctime>
 24
 25 using namespace std;
 26 #define LL long long
 27 int fm;
 28 int ok;
 29 const int inf = ~0U>>1;
 30 class treap
 31 {
 32    struct node{
 33        int value , key ,num;
 34        node (int v, node *n):value(v)
 35        {
 36          c[0] = c[1] = n ;num = 1 ;  key = rand()-1;
 37        }
 38        node *c[2];
 39    }*root ,*null;
 40    void rot(node *&t , bool d)
 41    {
 42       node *c = t->c[d];
 43       t->c[d] = c->c[!d];
 44       c->c[!d] = t;
 45       t = c;
 46    }
 47    void insert(node *&t ,int x)
 48    {
 49      if(t == null)
 50      {
 51         t= new node(x,null);
 52         return ;
 53      }
 54      if(x == t->value){
 55         t->num ++ ;
 56         return ;
 57      }
 58      bool d = x > t->value;
 59      insert(t->c[d],x);
 60      if(t->c[d]->key < t->key)
 61          rot(t,d);
 62    }
 63    void Delete(node *&t ,int x)
 64    {
 65        if(t == null)
 66        {
 67         ok = 0 ;
 68         return ;
 69        }
 70        if(t->value == x && t->num != 1)
 71        {
 72           //printf("2*****");
 73           t->num -- ;
 74           return ;
 75        }
 76        if(t->value  == x)
 77        {
 78          // printf("1*****");
 79           bool d = t->c[1]->key < t->c[0]->key;
 80           if(t->c[d] == null)
 81           {
 82             delete t;
 83             t = null ;
 84             return ;
 85           }
 86           rot(t,d);
 87           Delete(t->c[!d],x);
 88        }else{
 89          bool d  = x > t->value;
 90          Delete(t->c[d],x);
 91        }
 92    }
 93    void find(node *t , int x)
 94    {
 95         if(t == null)
 96             return ;
 97        // printf("%d**\n",t->value);
 98         if(t->value >= x)
 99         {
100               ok = 1;
101             fm = min(fm,t->value);
102             find(t->c[0],x);
103         }else{
104             find(t->c[1],x);
105         }
106    }
107    void Free(node *t)
108    {
109        if(t == null)
110            return ;;
111        if(t->c[1] != null)
112            Free(t->c[1]);
113        if(t->c[0] != null)
114            Free(t->c[0]);
115        delete t ;
116        t = null;
117    }
118     public:
119        treap()
120        {
121           null = new node(0,0);
122           null->num = 0 ;
123           null->key = inf;
124           root = null;
125        }
126        void ins(int x)
127        {
128           insert(root,x);
129        }
130        void del(int x)
131        {
132           Delete(root ,x);
133        }
134        void   f(int x)
135        {
136            find(root,x);
137        }
138        void fre()
139        {
140           Free(root);
141        }
142
143 };
144 struct node1{
145   int x, y ;
146 }K[100005];
147 bool cmp(node1 x, node1 y)
148 {
149     if(x.x == y.x)
150        return x.y > y.y;
151     return x.x > y.x ;
152 }
153 int main(){
154    int n , m;
155    while(scanf("%d %d",&n,&m) != EOF)
156    {
157         treap T[104];
158         for(int i =1 ;i <= n;i ++)
159         {
160            int a, b ;
161            scanf("%d %d",&a,&b);
162            T[b].ins(a);
163         }
164         int num  = 0 ;
165         LL sum = 0 ;
166         for(int i =1 ;i <= m;i ++)
167         {
168            scanf("%d %d",&K[i].x,&K[i].y);
169         }
170         sort(K+1,K+1+m,cmp);
171         for(int i =1;i <= m;i ++){
172            int a, b;
173            a = K[i].x;
174            b = K[i].y;
175            for(int j = b ;j <= 100;j ++)
176            {
177               ok = 0 ;
178               fm = 1e9;
179               T[j].f(a);
180              // printf("%d %d\n",fm,ok);
181               if(ok == 1)
182               {
183                  T[j].del(fm);
184                  sum += 500*a+2*b ;
185                  num ++ ;
186                  break;
187               }
188            }
189         }
190     //    for(int i =1 ;i <= 100 ;i ++)
191     //        T[i].fre();
192         printf("%d %I64d\n",num,sum);
193    }
194 return 0;
195 }

HDU4846Task treap + 贪心,布布扣,bubuko.com

时间: 2024-09-29 01:34:02

HDU4846Task treap + 贪心的相关文章

BZOJ 1691: [Usaco2007 Dec]挑剔的美食家 [treap 贪心]

1691: [Usaco2007 Dec]挑剔的美食家 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 786  Solved: 391[Submit][Status][Discuss] Description 与很多奶牛一样,Farmer John那群养尊处优的奶牛们对食物越来越挑剔,随便拿堆草就能打发她们午饭的日子自然是一去不返了.现在,Farmer John不得不去牧草专供商那里购买大量美味多汁的牧草,来满足他那N(1 <= N <= 100,

【贪心+Treap】BZOJ1691-[Usaco2007 Dec]挑剔的美食家

[题目大意] 有n头奶牛m种牧草,每种牧草有它的价格和鲜嫩度.每头奶牛要求它的牧草的鲜嫩度要不低于一个值,价格也不低于一个值.每种牧草只会被一头牛选择.问最少要多少钱? [思路] 显然的贪心,把奶牛和牧草都按照鲜嫩度由大到小排序,对于每奶牛把鲜嫩度大于它的都扔进treap,然后找出后继. 不过注意后继的概念是大于它且最小的,然而我们这里是可以等于的,所以应该是找cow[i].fresh-1的后继,注意一下…… 1 #include<iostream> 2 #include<cstdio&

BZOJ 2809 APIO2012 dispatching Treap+启示式合并 / 可并堆

题目大意:给定一棵树,选定一棵子树中的一些点,薪水和不能超过m,求点的数量*子树根节点的领导能力的最大值 考虑对于每一个节点,我们维护一种数据结构,在当中贪心寻找薪金小的雇佣. 每一个节点暴力重建一定不行.我们考虑可并数据结构.每一个节点将子节点的信息直接合并就可以 能够用启示式合并的Treap.也能够用可并堆 今天特意去学了这玩应0.0 先写了左偏树 然后又写了下随机堆-- 后者速度上更快一些 只是建议从左偏树開始学起 总之平衡树常数各种大就是了0.0 Treap+启示式合并 #include

BZOJ 2809 APIO2012 dispatching Treap+启发式合并 / 可并堆

题目大意:给定一棵树,选定一棵子树中的一些点,薪水和不能超过m,求点的数量*子树根节点的领导能力的最大值 考虑对于每个节点,我们维护一种数据结构,在其中贪心寻找薪金小的雇佣. 每个节点暴力重建一定不行,我们考虑可并数据结构,每个节点将子节点的信息直接合并即可 可以用启发式合并的Treap,也可以用可并堆 今天特意去学了这玩应0.0 先写了左偏树 然后又写了下随机堆-- 后者速度上更快一些 不过建议从左偏树开始学起 总之平衡树常数各种大就是了0.0 Treap+启发式合并 #include<cst

启发式合并(堆、set、splay、treap)/线段树合并学习小记

启发式合并 刚听到这个东西的时候,我是相当蒙圈的.特别是"启发式"这三个字莫名的装逼,因此之前一直没有学. 实际上,这个东西就是一个SB贪心. 以堆为例,若我们要合并两个堆a.b,我们有一种极其简单的做法:那就是比较一下它们的大小,将小的堆的每个元素依次插入到大的堆中.不妨设\(|a|≤|b|\),则时间复杂度即为:\(O(|a|*log_2(|a|+|b|))\). 这个东西看似很慢,但当点数较小的时候,我们可以证明复杂度是可被接受的. 比如我们要合并n个堆,这n个堆共有m个点.设这

Treap

先推荐一篇文章和黄学长的代码http://hzwer.com/1712.html    https://wenku.baidu.com/view/c8c11e1e650e52ea55189887.html 黄学长的代码既不用指针又很短,真心推荐 Treap,顾名思义,Tree+Heap,它既满足二叉搜索树的性质,又满足堆的性质 对于二叉搜索树,如果我们把数有序加入,那么它的时间效率会退化成O(n). 我们引入一个随机数(即下文描述的修正值),使得随机数满足堆的性质(小根堆或大根堆,不一定要是完全

【uva 1615】Highway(算法效率--贪心 区间选点问题)

题意:给定平面上N个点和一个值D,要求在x轴上选出尽量少的点,使得对于给定的每个店,都有一个选出的点离它的欧几里德距离不超过D. 解法:先把问题转换成模型,把对平面的点满足条件的点在x轴的直线上可得到一个个区间,这样就是选最小的点覆盖所有的区间的问题了.我之前的一篇博文有较详细的解释:关于贪心算法的经典问题(算法效率 or 动态规划).代码实现我先空着.挖坑~

POJ1017 Packets(贪心算法训练)

Time Limit: 1000MS          Memory Limit: 10000K          Total Submissions: 51306          Accepted: 17391 Description A factory produces products packed in square packets of the same height h and of the sizes 1*1, 2*2, 3*3, 4*4, 5*5, 6*6. These pro

ZOJ 3946 Highway Project 贪心+最短路

题目链接: http://www.icpc.moe/onlinejudge/showProblem.do?problemCode=3946 题解: 用dijkstra跑单元最短路径,如果对于顶点v,存在一系列边(ui,v)使得dis[v]最小(dis[v]表示0到v的距离).这些边能且只能选一条,那么我们自然应该选cost最小的那个边了. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #inc