The ACM ICPC’s rule of scoring is as the following:
A problem is solved when it is accepted by the judges. Teams are ranked according to the most problems solved. For the purposes of awards, or in determining qualifier(s) for the World Finals, teams who solve the same number of problems are ranked by least total time. The total time is the sum of the time consumed for each problem solved. The time consumed for a solved problem is the time elapsed from the beginning of the contest to the submittal of the accepted run plus 20 penalty minutes for every rejected run for that problem regardless of submittal time. There is no time consumed for a problem that is not solved.
For example, if one has the following contest record:
Then his total time = (150+20) + 160 = 330. Notice that it took him only 10 minutes to finish problem C. Assume that he spent 40 minutes on reading all the problems through, then if he could do problem C first and problem A last, his contest record might look like:
Then his total time would be 50 + (100+20) = 170. Hence the order of solving the problems will affect one’s final rank.
Now suppose that you are in a one-person team. It will take you t0 minutes to read all the problems through. Judging by your experience, you may estimate the minutes ti that you will take to solve problem i . And more, the earlier you get one problem done, the more unlikely that you will make mistakes on programming. Assume that if a solution is first time submitted in the first hour (60 minutes inclusive), it will get accepted at once; if it is first time submitted in the second hour, it will be rejected once; if it is first time submitted in the third hour, it will be rejected twice; etc. You may also estimate the minutes di for debugging problem i every time it is rejected. For the sake of simplicity, let us assume that di is fixed for each problem i , and once you start working on a problem, you will keep submitting until it is accepted.
Your task is to write a program to find yourself the order of solving the problems which gives you the best chance of winning the contest.
Each input file contains several test cases. For each test case, the 1st line contains 3 integers: the total number of contest hours H
( 0<H≤5 ), the total number of problems N
( 0<N≤9 ), and the time t0 (minutes) for you to read through all the problems at the beginning of the contest. The following N
lines each contains a problem’s name and a pair of positive integers ti and di . A problem’s name is a string of no more than 20 characters without any space. A negative H
signals the end of input.
For each test case, you are supposed to print to standard output the total time in a line in the format shown by the sample. Then print the names of the problems you will solve in the correct order, each name in a line. If there are several solutions, you must output the smallest sequence. A sequence of problems {i1,i2,...in} is smaller than another sequence {j1,j2,...jn} means that there exists an integer K between 1 and n such that for every 1≤k<K , we have ik=jk , and iK<jK .
2 3 40
A 60 10
B 40 10
C 10 20
2 3 40
Try_This_One 20 5
And_This_One 20 5
Then_This_One 20 5
-1
Total Time = 170
C
B
Total Time = 295
Try_This_One
And_This_One
Then_This_One
按照ACM/ICPC的比赛计分规则(解题数+20分钟罚时规则),给定比赛时间、总题数。
假设某个人是这样做题的:
1. 用一定时间通读所有的题,计算出解出每个题目所需的时间,以及如果错了,调试一次所需的时间。
2. 他一旦开始做某题,不做出来就不换题(一不做二不休)。
3. 对于每道题,他第一次提交的时间决定了他需要调试的次数。
具体地说是这样的:
问题是要帮他确定一个可以获得尽量高排名的做题顺序:在解题量尽量高的前提下让罚时尽量小。
对于 N 道题规模的暴力搜索的时间复杂度是 O(N⋅N!) 。
然而题目的规模不大, N≤9 ,可取。
完全模拟真实比赛进程就可以了,由此可以得到两个基本的搜索出口:比赛时间到、题目全部解出(AK)。
每当到达搜索出口时,要将当前解与当前最优解比较并试图更新(最优解合并),这里需要 O(N) 的时间。
这个问题呢,仅以N为因子则时间复杂度不可能降低,最优算法即 O(N⋅N!) ,原因是你总是需要生成解题顺序的全排列来计算最优的方案。比如在比赛时长足够长(无限)的情况下,这也是一个有后效性的问题,不存在动态规划解。
PTA Review of Programming Contest Rules 暴力搜索