原始节目描述是:
鞋匠有N个客户的订单,他必须满足。鞋匠每天只能从事一项工作,工作通常需要几天时间。对于第i个工作,整数Ti(1 $ \ le $ Ti $ \ le $ 1,000)表示鞋匠完成工作所需的天数。
但人气有其代价。对于开始从事第i个工作之前的每一天延迟,该鞋匠已同意每天支付罚款Si(1 $ \ $ $ $ $ $ $ 10,000美分)。通过编写程序帮助鞋匠找到最小总罚款的工作顺序。
输入
输入以一行上的单个正整数开头,表示测试用例的数量,后跟一个空行。两个连续案件之间也有一个空白。
每个案例的第一行包含一个报告作业数N的整数,其中1 $ \ le $ N $ \ le $ 1,000。第i行后续行包含第i个工作的完成时间Ti和每日惩罚Si
输出
对于每个测试用例,您的程序应该以最小的罚款打印作业序列。每个工作都应该由其在输入中的位置来表示。所有整数应仅放在一个输出行上,每对由一个空格分隔。如果可以使用多种解决方案,请按字典顺序打印第一个解决方案。
两个连续案例的输出必须用空行分隔。
示例输入
1
4 3 4 1 1000 2 2 5 5 样本输出
2 1 3 4
在互联网上,我认为最好的解决方案是贪婪的工作时间和罚款的比例。但我不认为它就像不言自明一样简单,那么如何严格证明呢?谢谢!
答案 0 :(得分:0)
谢谢,@ mrmcgrep。我得到了答案:
让我们说我们有工作1,2,...,n,他们有时间和精细t1,f1,t2,f2,...,tn,fn
它们的顺序为t1 / f1< = t2 / f2< = t3 / f3< = ...< = tn / fn
所以这是客观的时间表。现在我们用m(1< m< = n)
改变1按照原始订单,我们需要支付罚款: F1 = t1 *(f2 + ... + fn)+ t2 *(f3 + ... + fn)+ ... + tm *(fm + 1 + ... + fn)+ R
根据新订单,我们需要支付罚款: F2 = tm *(f1 + ... + fm-1 + fm + 1 + ... + fn)+ t1 *(f2 + ... + fm-1 + fm + 1 + ... + fn)+ ...... + fm-1 * fm + 1 + ... + fn)+ R
F1 - F2 =(t1 + t2 + ... + tm-1)* fm - (tm * f1 + tm * f2 + ... + tm * fm-1)
当t1 * fm <= tm * f1时,t2 * fm&lt; = tm * f2,...,tm-1 * fm&lt; = tm * fm-1 F1-F2 <= 0
所以原始订单是最好的订单。