题目描述

给出\(N\)件单位时间任务,对于第\(i\)件任务,如果要完成该任务,需要占用\([S_i, T_i]\)间的某个时刻,且完成后会有\(V_i\)的收益。求最大收益。

澄清:一个时刻只能做一件任务,做一个任务也只需要一个时刻。

输入格式

第一行一个整数\(N\),表示可供选择的任务个数。

接下来的第二到第\(N+1\)行,每行三个数,其中第\(i+1\)行依次为\(S_i,T_i,V_i\)。

输出格式

输出最大收益

样例

样例输入1

  1. 2
  2. 1 1 1
  3. 1 1 2

样例输出1

  1. 2

样例输入2

  1. 3
  2. 1 1 5
  3. 2 2 3
  4. 1 2 4

样例输出2

  1. 9

样例输入3

  1. 6
  2. 1 2 10
  3. 2 3 10
  4. 3 4 10
  5. 4 5 10
  6. 1 1 5
  7. 5 5 6

样例输出3

  1. 46

数据范围

在所有数据中,\(N\leq5000,1\leq S_i\leq 10^8,1\leq V_i \leq 10^8\)。

题解

我又诈尸了。

来到中山纪中集训,省选组的题目第一天就这么神(集训队的题能不神么)……真是\(Orz\),咱全场几乎爆零成功垫底。

回到题目,直接说正解。考虑将任务的价值从大到小排序,假设我们已经安排好了前\(i-1\)个任务,其中要完成的任务集合是\(S\)。如果要完成第\(i\)个任务会导致原来处于\(S\)的任务中的一个无法完成,那么我们果断放弃第\(i\)个任务(因为如果换做完成\(i\),并没有腾出更多时间,但却丢失了更多价值),否则我们没有理由不完成\(i\)个任务。

那么我们只需要完成一步就好了,那就是判断将任务\(i\)加入集合\(S\)后是否能让所有任务都能找到时间做。这个东西我们可以用一个简单粗暴的方法,每次从任务\(i\)的起始时间开始找,如果这个时间没有被占领,那么占领,结束。否则找到占领该时间的任务,记作\(j\)。此时就存在一个选择,到底是让\(i\)去后面找时间还是让\(j\)找?显然,能拖得更久的任务去尝试更好,也就是结束时间更晚的那一个去找。就这样递归下去,直到不冲突或者超出任务的结束时间为止(超出了当然就得放弃任务了……)。每次最多遇到\(i-1\)次冲突(因为最多也只有\(i-1\)个任务),判断一次的复杂度是\(O(n)\)的。

这里有一个空间上的优化。其实有用的时间其实并不多,我们将他们记为“活跃点”。我们从每个任务的起始时间开始找,找到第一个空位,就将它加入“活跃点”,显然只考虑活跃点的情况下仍然可以达到最优,这样可以把空间也优化到\(O(n)\)(然而代价是时间复杂度有了离散化时的\(log\))。

\(Code:\)

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. #include <algorithm>
  5. using namespace std;
  6. #define N 5005
  7. #define ll long long
  8. int n;
  9. struct node
  10. {
  11. int s, t, v;
  12. }S[N];
  13. bool cmp1(node a, node b){return a.s < b.s;}
  14. bool cmp2(node a, node b){return a.v > b.v;}
  15. int data[N], plc[N];
  16. int Find(int x, int p)
  17. {
  18. if (p > S[x].t)
  19. return 0;
  20. if (!plc[p])
  21. {
  22. plc[p] = x;
  23. return 1;
  24. }
  25. if (S[plc[p]].t < S[x].t)
  26. return Find(x, p + 1);
  27. if (Find(plc[p], p + 1))
  28. {
  29. plc[p] = x;
  30. return 1;
  31. }
  32. return 0;
  33. }
  34. int main()
  35. {
  36. scanf("%d", &n);
  37. for (int i = 1; i <= n; i++)
  38. scanf("%d%d%d", &S[i].s, &S[i].t, &S[i].v);
  39. sort(S + 1, S + n + 1, cmp1);
  40. for (int i = 1; i <= n; i++)
  41. data[i] = max(data[i - 1] + 1, S[i].s);
  42. for (int i = 1; i <= n; i++)
  43. {
  44. S[i].s = lower_bound(data + 1, data + n + 1, S[i].s) - data;
  45. S[i].t = upper_bound(data + 1, data + n + 1, S[i].t) - data - 1;
  46. }
  47. sort(S + 1, S + n + 1, cmp2);
  48. ll ans = 0;
  49. for (int i = 1; i <= n; i++)
  50. if (Find(i, S[i].s))
  51. ans += S[i].v;
  52. printf("%lld\n", ans);
  53. }

「中山纪中集训省选组D1T1」最大收益 贪心的更多相关文章

  1. 「中山纪中集训省选组D4T1」折射伤害 高斯消元

    题目描述 在一个游戏中有n个英雄,初始时每个英雄受到数值为ai的伤害,每个英雄都有一个技能"折射",即减少自己受到的伤害,并将这部分伤害分摊给其他人.对于每个折射关系,我们用数对\ ...

  2. 「中山纪中集训省选组D2T1」书堆 欧拉常数

    题目描述 蚂蚁是勤劳的动物,他们喜欢挑战极限.现在他们迎来了一个难题!蚂蚁居住在图书馆里,图书馆里有大量的书籍.书是形状大小质量都一样的矩形.蚂蚁要把这些书摆在水平桌子的边缘.蚂蚁喜欢整洁的布置,所以 ...

  3. 中山纪中集训Day5叒是测试(划淼)

    A组T1 矩阵游戏(game) 九校联考24OI__D1T1 问题描述 LZK发明一个矩阵游戏,大家一起来玩玩吧,有一个N行M列的矩阵.第一行的数字是1,2,…M,第二行的数字是M+1,M+2…2*M ...

  4. 中山纪中集训Day1测试(摸鱼)

    AT3 粉刷匠 Description 赫克托是一个魁梧的粉刷匠,而且非常喜欢思考= = 现在,神庙里有N根排列成一直线的石柱,从1到N标号,长老要求用油漆将这些石柱重新粉刷一遍.赫克托有K桶颜色各不 ...

  5. 中山纪中集训Day4双是测试(划沝) 九校联考-DL24凉心模拟Day2

    A组T1 锻造 (forging) 1.1 题目背景 勇者虽然武力值很高,但在经历了多次战斗后,发现怪物越来越难打于是开始思考是不是自己平时锻炼没到位,于是苦练一个月后发现......自己连一个史莱姆 ...

  6. 中山纪中集训Day2又是测试(划水)

    A组T1 bzoj 2674 Attack Description chnlich 非常喜欢玩三国志这款游戏,并喜欢用一些策略出奇制胜.现在,他要开始征服世界的旅途了.他的敌人有N 座城市和N 个太守 ...

  7. 纪中集训 Day 2

    今天(其实是昨天= =)早上起来发现好冷好冷啊= = 吃完饭就准备比赛了,好吧B组难度的题总有一道不知到怎么写QAQ 太弱了啊!!! 蒟蒻没人权啊QAQ 今天第4题不会写,在这里说说吧 题目的意思就是 ...

  8. 纪中集训 Day1

    今天早上起来吃饭,发现纪中伙食真的是太差了!!!什么都不热,早餐的面包还好,然后就迎来了美好的早晨= = 早上做一套题,T1T2果断秒,T3一看就是noi原题,还好看过题解会写,然后就愉快的码+Deb ...

  9. 洛谷P1880 [NOI1995]石子合并 纪中21日c组T4 2119. 【2016-12-30普及组模拟】环状石子归并

    洛谷P1880 石子合并 纪中2119. 环状石子归并 洛谷传送门 题目描述1 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石 ...

随机推荐

  1. js 数组 : 差集、并集、交集、去重、多维转一维

    //input:[{name:'liujinyu'},{name:'noah'}] //output:['liujinyu','noah'] Array.prototype.choose = func ...

  2. [HTML5] Native lazy-loading for the web

    According to HTTPArchive, images are the most requested asset type for most websites and usually tak ...

  3. Direction of Arrival Based Spatial Covariance Model for Blind Sound Source Separation

    基于信号协方差模型DOA的盲声源分离[1]. 在此基础上,作者团队于2018年又发布了一篇文章,采用分级和时间差的空间协方差模型及非负矩阵分解的多通道盲声源分离[2]. 摘要 本文通过对短时傅立叶变换 ...

  4. TimescaleDB1.3 的新特性——Continuous aggregates: faster queries with automatically maintained materialized views

    One characteristic of time-series data workloads is that the dataset will grow very quickly. Without ...

  5. 洛谷 P3905 道路重建 题解

    P3905 道路重建 题目描述 从前,在一个王国中,在\(n\)个城市间有\(m\)条道路连接,而且任意两个城市之间至多有一条道路直接相连.在经过一次严重的战争之后,有\(d\)条道路被破坏了.国王想 ...

  6. 查全率(Recall),查准率(Precision),灵敏性(Sensitivity),特异性(Specificity),F1,PR曲线,ROC,AUC的应用场景

    之前介绍了这么多分类模型的性能评价指标(<分类模型的性能评价指标(Classification Model Performance Evaluation Metric)>),那么到底应该选 ...

  7. UOJ46. 【清华集训2014】玄学 [线段树,二进制分组]

    UOJ 思路 模拟赛出了这题,结果我没学过二进制分组--一波主席树然后空间就爆炸了-- 用线段树维护时间序列,每个节点维护\(a_i\to x_i\times a_i+b_i,i\in [1,n]\) ...

  8. Healthcare in Azure

  9. maven依赖总结

    1.依赖元素 groupId,必选,实际隶属项目 artifactId,必选,其中的模块 version必选,版本号 type可选,依赖类型,默认jar scope可选,依赖范围,默认compile ...

  10. Java封装jar包对外提供可执行文件

    编写Main方法,封装jar包 1.编写Main方法 import java.util.Date; /** * 描述 : * * @Author : zhanghao * @Time : 2019/1 ...