目录
题目描述
资源限制
内存限制:256.0MB C/C++时间限制:1.0s Java时间限制:3.0s Python时间限制:5.0s
问题描述
丑枫接到了一份奇葩的工作:往冰库里搬运冰块.冰库外放着N箱冰块,由于室外温度高,冰块会很快融化,且每箱冰块的融化速度不同.因为每箱冰块的体积,质量不等,把每箱冰块搬运进冰块花费的时间也不同.因此需要合理安排搬运顺序,才能使总的冰块融化量最小.丑枫请你帮忙计算最少的总融化量是多少,以便汇报上司.
输入格式
第一行输入整数N
接下来N行,每行两个整数,分别表示每箱冰块的搬运耗时Ti及融化速度Di.
输出格式
输出最少的总融化量
样例输入
6
6 1
4 5
4 3
6 2
8 1
2 6
样例输出
86
数据规模和约定
2<=N<=100000,1<=Ti<=4000000,1<=Di<=100
样例说明
按照6、2、3、4、1、5的顺序搬运
分析
通过题意我们知道决定先后顺序的是冰块的搬运时间和融化速度,根据生活经验,我们会把融化的快的先搬进冰库快的先搬(即 Di 比较大的 ),但是如果融化速度即Di一样的,我们会看哪个比较轻,也就是搬运速度比较快,即 TI 较小的。
总的来说,就是Di越大,Ti越小的,就先搬。
所以我们可以把 Ti 和 Di 进行组合,即 Ti / Di 或者 Di / Ti ,我这里用 Ti / Di 来演示。即得出来的值越小,顺序越靠前。
代码(java)
先创建一个类,作为一个用来保存冰块的搬运时间和融化速度。
class poin{
int t; //代表搬运时间
int d; //代表融化速度
public poin(int t,int d) {
this.t=t;
this.d=d;
}
}
创建一个队列保存输入的数据,在保存数据的同时,记录总的融化速度,方便计算融化量
List<poin> list=new ArrayList<poin>(); //保存输入的冰块数据
int sum=0; //即录冰块的总融化速度
while(n-->0) {
int a=sc.nextInt();
int b=sc.nextInt();
sum+=b;
list.add(new poin(a,b));
}
我们根据上面的分析可以得到 Ti/Di 的值最小的先搬,所以我们可以先按先后顺序排序。
我这里用自带的sort排序方法,重写compare方法,使其按照 Ti / Di 的值 进行排序。
list.sort(new Comparator<poin>() {
@Override
public int compare(poin o1, poin o2) {
// TODO Auto-generated method stub
if(o1.t==o2.t&&o1.d==o2.d) {
return 0;
}
double mu1=(double)o1.t/o1.d;
double mu2=(double)o2.t/o2.d;
if(mu1>mu2) {
return 1;
}else {
return -1;
}
}
});
排好序后就可以直接计算了,用搬运冰块消耗的时间乘上总的融化时间。每计算一个删除掉一个。直到队列为空。第一次运行它给的例子,发现答案不对,然后把搬运中的冰块算作不会融化才行。也就是要把每次要搬运的冰块融化速度从总的融化速度中去掉。
long lon=0; //记录总融化量
while(!list.isEmpty()) { //队列空结束循环
poin p=list.get(0); //取出排在第一位的冰块
list.remove(0); //从队列中去除
sum-=p.d; //该冰块搬运时不会融化
lon+=p.t*sum; //累加在搬运时的融化量
}
完整代码
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
List<poin> list=new ArrayList<poin>();
int sum=0;
while(n-->0) {
int a=sc.nextInt();
int b=sc.nextInt();
sum+=b;
list.add(new poin(a,b));
}
list.sort(new Comparator<poin>() {
@Override
public int compare(poin o1, poin o2) {
// TODO Auto-generated method stub
if(o1.t==o2.t&&o1.d==o2.d) {
return 0;
}
double mu1=(double)o1.t/o1.d;
double mu2=(double)o2.t/o2.d;
if(mu1>mu2) {
return 1;
}else {
return -1;
}
}
});
long lon=0;
while(!list.isEmpty()) {
poin p=list.get(0);
list.remove(0);
sum-=p.d;
lon+=p.t*sum;
}
System.out.println(lon);
}
}
class poin{
int t;
int d;
public poin(int t,int d) {
this.t=t;
this.d=d;
}
}
运行效果