排队打水
题解:
t
1
,
t
2
,
t
3
,
.
.
.
,
t
n
−
1
,
t
n
t_1,t_2,t_3, ...,t_{n-1},t_n
t1,t2,t3,...,tn−1,tn
等待时间计算的公式为:
t
1
∗
(
n
−
1
)
+
t
2
∗
(
n
−
2
)
+
.
.
.
+
t
n
−
1
∗
1
t_1*(n-1)+t_2*(n-2)+...+t_{n-1}*1
t1∗(n−1)+t2∗(n−2)+...+tn−1∗1
当
t
1
,
t
2
,
t
3
,
.
.
.
,
t
n
−
1
,
t
n
t_1,t_2,t_3, ...,t_{n-1},t_n
t1,t2,t3,...,tn−1,tn为单调递增数列时,等待时间最小。
证明:
利用反证法,设排队顺序中存在
t
i
>
t
i
+
1
t_i>t_{i+1}
ti>ti+1
那么花在排在第
i
i
i个人上的等待时间为
t
i
∗
(
n
−
i
−
1
)
t_i*(n-i-1)
ti∗(n−i−1)
花在排在第
i
+
1
i+1
i+1个人上的等待时间为
t
i
+
1
∗
(
n
−
i
−
2
)
t_{i+1}*(n-i-2)
ti+1∗(n−i−2)
那么
t
i
∗
(
n
−
i
−
1
)
+
t
i
+
1
∗
(
n
−
i
−
2
)
t_i*(n-i-1)+t_{i+1}*(n-i-2)
ti∗(n−i−1)+ti+1∗(n−i−2)为这两个人打水的等待成本
若将排在第
i
+
1
i+1
i+1个人和第
i
i
i个人交换位置。
那么
t
i
∗
(
n
−
i
−
2
)
+
t
i
+
1
∗
(
n
−
i
−
1
)
t_i*(n-i-2)+t_{i+1}*(n-i-1)
ti∗(n−i−2)+ti+1∗(n−i−1)为这两个人交换位置后的等待成本
未交换位置和交换位置后的等待时间成本作差,可得
t
i
−
t
i
+
1
t_i-t_{i+1}
ti−ti+1因为
t
i
>
t
i
+
1
t_i>t_{i+1}
ti>ti+1所以,交换位置前的等待时间成本大于交换位置后的,所以排队顺序中不应该存在排在前方的人的打水时间大于排在后方的人的打水时间的非单调递增的情况。
import java.io.*;
import java.util.*;
public class Main{
static int N=100010;
public static void main(String[] args)throws IOException{
BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
int n=Integer.parseInt(in.readLine());
String[] strs=in.readLine().split(" ");
int[] t=new int[N];
for(int i=0;i<n;i++)
t[i]=Integer.parseInt(strs[i]);
Arrays.sort(t,0,n);
long sum=0;
for(int i=0;i<n;i++){
sum+=t[i]*(n-i-1);
}
System.out.println(sum);
}
}
货仓选址
import java.io.*;
import java.util.*;
public class Main{
static int N=100010;
static int[] loc=new int[N];
public static void main(String[] args)throws IOException{
BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
int n=Integer.parseInt(in.readLine());
String[] strs=in.readLine().split(" ");
for(int i=0;i<n;i++)
loc[i]=Integer.parseInt(strs[i]);
Arrays.sort(loc,0,n);
int d=loc[n/2];
int res=0;
for(int i=0;i<n;i++)
res+=Math.abs(d-loc[i]);
System.out.println(res);
}
}
耍杂技的牛
题解
按照
w
i
+
s
i
w_i+s_i
wi+si从小到大的顺序排,最大的危险系数一定是最小的
假设存在
w
i
+
s
i
>
w
i
+
1
+
s
i
+
1
w_i+s_i>w_{i+1}+s_{i+1}
wi+si>wi+1+si+1
则有:
第 i i i个位置上的牛 | 第 i + 1 i+1 i+1个位置上的牛 | |
---|---|---|
交换前 | w 1 + w 2 + . . . + w i − 1 − s i w_1+w_2+...+w_{i-1}-s_{i} w1+w2+...+wi−1−si | w 1 + w 2 + . . . + w i − 1 + w i − s i + 1 w_1+w_2+...+w_{i-1}+w_i-s_{i+1} w1+w2+...+wi−1+wi−si+1 |
交换后 | w 1 + w 2 + . . . + w i − 1 − s i + 1 w_1+w_2+...+w_{i-1}-s_{i+1} w1+w2+...+wi−1−si+1 | w 1 + w 2 + . . . + w i − 1 + w i + 1 − s i w_1+w_2+...+w_{i-1}+w_{i+1}-s_i w1+w2+...+wi−1+wi+1−si |
同时去掉 w 1 + w 2 + . . . + w i − 1 w_1+w_2+...+w_{i-1} w1+w2+...+wi−1
第 i i i个位置上的牛 | 第 i + 1 i+1 i+1个位置上的牛 | |
---|---|---|
交换前 | − s i -s_{i} −si | w i − s i + 1 w_i-s_{i+1} wi−si+1 |
交换后 | − s i + 1 -s_{i+1} −si+1 | w i + 1 − s i w_{i+1}-s_i wi+1−si |
同时加上 s i + s i + 1 s_i+s_{i+1} si+si+1
第 i i i个位置上的牛 | 第 i + 1 i+1 i+1个位置上的牛 | |
---|---|---|
交换前 | s i + 1 s_{i+1} si+1 | w i + s i w_i+s_i wi+si |
交换后 | s i s_{i} si | w i + 1 + s i + 1 w_{i+1}+s_{i+1} wi+1+si+1 |
因为
w
i
>
1
w_i>1
wi>1,所以
w
i
+
s
i
>
s
i
w_i+s_i>s_i
wi+si>si,
因为假设的
w
i
+
s
i
>
w
i
+
1
+
s
i
+
1
w_i+s_i>w_{i+1}+s_{i+1}
wi+si>wi+1+si+1,所以综上
m
a
x
(
s
i
+
1
,
w
i
+
s
i
)
>
m
a
x
(
s
i
,
w
i
+
1
+
s
i
+
1
)
max(s_{i+1},w_i+s_i)>max(s_i,w_{i+1}+s_{i+1})
max(si+1,wi+si)>max(si,wi+1+si+1)
交换前第
i
i
i个位置上的牛和第
i
+
1
i+1
i+1个位置上的牛的最大风险值要大于交换后的第
i
i
i个位置上的牛和第
i
+
1
i+1
i+1个位置上的牛的最大风险值。
所以综上来说,让
w
i
+
s
i
w_i+s_i
wi+si小的排上面这两头牛最大风险值更小,总体的排序也同理。
import java.io.*;
import java.util.*;
class Cow implements Comparable<Cow>{
int w;
int s;
public Cow(int w,int s){
this.w=w;
this.s=s;
}
public int compareTo(Cow o){
return Integer.compare(w+s,o.w+o.s);
}
}
public class Main{
static int N=50010;
static Cow[] cow=new Cow[N];
public static void main(String[] args)throws IOException{
BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
int n=Integer.parseInt(in.readLine());
String[] strs;
for(int i=0;i<n;i++){
strs=in.readLine().split(" ");
int w=Integer.parseInt(strs[0]);
int s=Integer.parseInt(strs[1]);
cow[i]=new Cow(w,s);
}
Arrays.sort(cow,0,n);
int risk=-cow[0].s;
int tw=cow[0].w;
for(int i=1;i<n;i++){
int res=tw-cow[i].s;
tw+=cow[i].w;
if(res>risk)risk=res;
}
System.out.println(risk);
}
}