嗯...一个看着简单越写越想撞墙的题...20分弃坑...这里写的只是做题时候的思路,欢迎指正。
===========================原题==========================
该机器有两个 CPU 和一个 GPU。对于每个任务,你可以为它分配不 同的硬件资源:
1. 在单个 CPU 上运行。
2. 在两个 CPU 上同时运行。
3. 在单个 CPU 和 GPU 上同时运行。
4. 在两个 CPU 和 GPU 上同时运行。
一个任务开始执行以后,将会独占它所用到的所有硬件资源,不得中 断,直到执行结束为止。第 i 个任务用单个 CPU,两个 CPU,单个 CPU 加 GPU,两个 CPU 加 GPU 运行所消耗的时间分别为 a i,b i,c i 和 d i。
现在需要你计算出至少需要花多少时间可以把所有给定的任务完成。
接下来的 n 行每行有四个正整数 a i, b i, c i, d i(a i, b i, c i, d i 均不超过 10), 以空格隔开。
4 4 2 2
7 4 7 4
3 3 3 3
同时运行第一个任务(单 CPU 加上 GPU)和第三个任务(单 CPU), 它们分别在时刻 2 和时刻 3 完成。在时刻 3 开始双 CPU 运行任务 2,在 时刻 7 完成。
===========================思路==========================
首先读完题发现的第一点:
【加上GPU未必会加快速度,双CPU也不见得会显著提高效率。】
其次想到的就是双CPU时是否使用GPU完全没关系...毕竟两个CPU都是你的了...
为了方便我们约定一下符号缩写:
1 单CPU处理SCSingle CPU
2 双CPU处理DCDouble CPU
3 单CPU带GPUSCGSingle CPU and GPU
4 双CPU带GPUDCGDouble CPU and GPU
5 不做任何处理PASS
关于每一时刻可能有的状态及决策:
1、单CPU空闲,GPU占用:①SC②PASS
2、单CPU空闲,GPU空闲 :①SC②SCG③PASS
3、双CPU空闲:①SCG+SC②SC+SCG③SC+SC④DC(G)
4、双CPU占用:①PASS
关于SCG+SC ≠ SC+SCG 的情况举个例子就是
假如按某个规则取出的两个任务:
SCSCG
A108 SC(A)+SCG(B) = 11
B41 SCG(A)+SC(B) = 12
虽然和去出任务的条件有关,但...缺的就是很好的取出条件
第一次...决定用模拟+贪心
然后就是痛苦的挣扎= =、到底该如何决策双CPU空闲的时候用SC(G)+SC还是DC???
刚开始把DC情况分成了以下两种:
很明显只有在max(SC1, SC2) < DC1 + DC2 的时候应该使用DC,但考虑到后来的任务SC填补上缺口之后结果可能会出现变化,所以只有在当前判定的集合是余下全集的时候比较好用。
后来按照(2 * DC > SCG)的标准尝试判定了一下发现也可以举出特别多反例,于是放弃。
模拟思路的最后挣扎是根据分类排了一个优先顺序:
① DC集:按SCG与DC差值降序排列
② SCG集:按SC与SCG差值降序排列
③ SC集:按SC值升序排列
想起来之前的最小代价归并问题,想要打个flag之后从三个集合里按顺序取符合条件的,勤勤恳恳写了一大圈最后竟然写成了一个剪枝的思路,判别DC的方法还是没找到。(期间也尝试了最后一个任务再判断是否DC,跑得更远)
之后就是第二个坑:深搜+剪枝,主要思路就是尝试了上面所有可能...
剪枝的地方: ① 时间已到达目前最小完成时间 - 返回
② 给定任务尝试顺序
③ 设定工作上限
④ 判断是否等待以尝试DC情况
⑤ 合并 SCG与SC混合情况(对比,不再分叉)
⑥ 有限度的尝试SC+SC情况
⑦ 两个CPU同时工作时直接跳转
... ...
写题用的时间太长,改到最后代码都乱了,超时的问题倒是解决了,又不知道哪里出错了。可能本来的思路就有漏洞或者直接跑歪了,找遍全世界也没个答案(连官方都没标程醉了...)。剪枝肯定还有能剪的地方,目前来看贪心也贪的不够,代码就不贴了,有大神路过跪求AC代码...