题目链接
zhx and contest
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 546 Accepted Submission(s): 192
Problem Description
As one of the most powerful brushes in the world, zhx usually takes part in all kinds of contests.
One day, zhx takes part in an contest. He found the contest very easy for him.
There are
n problems in the contest. He knows that he can solve the
ith problem in
ti units of time and he can get
vi points.
As he is too powerful, the administrator is watching him. If he finishes the
ith problem before time
li, he will be considered to cheat.
zhx doesn't really want to solve all these boring problems. He only wants to get no less than
w points. You are supposed to tell him the minimal time he needs to spend while not being considered to cheat, or he is not able to get enough points.
Note that zhx can solve only one problem at the same time. And if he starts, he would keep working on it until it is solved. And then he submits his code in no time.
Input
Multiply test cases(less than
50). Seek
EOF as the end of the file.
For each test, there are two integers
n and
w separated by a space. (
1≤n≤30,
0≤w≤109)
Then come n lines which contain three integers
ti,vi,li. (
1≤ti,li≤105,1≤vi≤109)
Output
For each test case, output a single line indicating the answer. If zhx is able to get enough points, output the minimal time it takes. Otherwise, output a single line saying "zhx is naive!" (Do not output quotation marks).
Sample Input
1 3 1 4 7 3 6 4 1 8 6 8 10 1 5 2 2 7 10 4 1 10 2 3
Sample Output
题意:点击打开链接
题解:将题目按(ti-li)从小到大排序,再按照这个顺序做题目显然是最优的。这样我们就解决了做题顺序的问题。接下若不考虑数据范围,该问题用背包、状态dp都能解决。由于n<=30,暴力枚举的复杂度是2^30。所以我想到用暴搜+剪枝的方法解决这题。
对于剪枝有两种:
最优性剪枝:如果当前的时间超过当前的最优解,则减掉
可行性剪枝:如果当前的得分+剩下的题目的总得分小于要求的得分,则减掉。
代码如下:
#include
#include
#include
#include
#include
#include
#include
#include
方法二:暴力枚举(BC官方题解的方法)
当然还是要按(l-t)把题目排序,解决做题顺序的问题。如果直接暴力枚举复杂度是O(2^30)。
我们可以把题目分成两份。按照排好的顺序前一半分成一份,后一半分成一份。
首先暴力枚举前一半题目,求出做前一半题目的所有可能得分即对应的时间。
以得分为优先从小到大排序,从前往后扫一遍处理出要至少得到该分要花的最少时间。
然后在暴力枚举后一半题目,求出相应的得分,并记录做了哪些题。然后再二分查找前一半至少要花多少时间才能使总分至少得到w,然后再求出最后要花多少时间即可。
复杂度O(2^15 * 15)
总结:如果直接暴力枚举要超时,可以尝试把枚举集合分成两部分(可能多部分),分别枚举,在合并得到最终答案。
代码如下:
#include
#include
#include
#include
#include
#include
#include
#include
方法3:题目按照(l-t)排序后,显然问题就是个背包问题。但是明显空间开不下,但是在背包的过程中其实有很多空间是无效的,没有用到的,所以我们可以用map来解决空间不够的问题,代码如下:
#include
#include
#include
#include
#include
#include
#include
#include