算法分析
- 安排他们的打水顺序才能使所有人的等待时间之和最小,则需要将打水时间最短的人先打水
证明:
不妨设
-
(1)i1 ≠ i2 ≠ i3 ≠ … ≠ in
-
(2)i1~in属于[1,n]
-
(3)t1 < t2 < t3 <… < tn,
1、由i
的任意性,打水的时间总和为ti1 * (n - 1) + ti2 * (n - 2) + … + tin * (n - n)
=n * (ti1 + ti2 +… + tin) - (ti1 * 1 + ti2 * 2 + … + tin * n)
2、即相当于求 ti1 * 1 + ti2 * 2 + … + tin * n 的最大值
3、假设ti1 , ti2 ,… , tin是按自然顺序排好序时是最大值,即Tmax = t1 * 1 + t2 * 2 + … + tn
4、任意选择两项ta∗x,tb∗(x+c),且ta < tb,c > 0,交换ta,tb位置得到tb∗x,ta∗(x+c) ,同时交换后不会对其他项造成影响
由于ta * x + tb * (x + c) = ta * x + tb * x + tb * c > ta * x + tb * x + ta * c = tb * x + ta * (x + c),即交换之后比原来的值更小.由于选取的任意性可得假设成立.
时间复杂度 O(nlogn)
Java 代码
import java.util.*;
public class Main{
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int[] a = new int[n + 1];
for(int i = 1;i <= n;i++)
{
a[i] = scan.nextInt();
}
Arrays.sort(a);
long res = 0;
for(int i = 1;i <= n;i++)
{
res += (a[i] * (n - i));
}
System.out.println(res);
}
}
????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
?????????????????????????????????????????????????????????????????????????????????????????????????????????
有bug哈哈哈哈
SJF
#include <bits/stdc++.h> using namespace std; const int N = 1e5+10; int q[N]; using LL = long long; int main() { int n;cin>>n; for(int i=0;i<n;++i)cin>>q[i]; sort(q,q+n); LL res=0; for(int i=0;i<n-1;++i) res+=q[i]*(n-1-i); cout<<res<<endl; return 0; }
思路一模一样兄弟
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e5+10; int n; ll res; int a[N]; int main() { cin>>n; for(int i=1;i<=n;i++)cin>>a[i]; sort(a+1,a+1+n); for(int i=1;i<n;i++) res+=a[i]*(n-i); cout<<res<<endl; return 0; }