题面:
https://ac.nowcoder.com/acm/contest/33189/A
大致题意:
你是服务器管理员,你现在要在n台服务器中选出m台进行运算,每台服务器都有各自的计算能力和传输效率,分别为和。服务器们不能同时运行,所以你要对选出的m台进行排序,最大限度地提高总计算效率。计算效率定义如下:
∑
i
=
1
m
w
a
i
∏
j
=
0
i
−
1
p
a
j
\sum_{i=1}^m w_{ai} \prod_{j=0}^{i-1} p_{aj}
i=1∑mwaij=0∏i−1paj
、等是你选出的服务器。为方便,=0,=1。
现在对此进行分析:
当我们选的服务器a[x]、a[y],满足y=x+1时
若x在前
总效率
R
=
∑
i
=
1
x
−
1
w
a
i
∏
j
=
0
i
−
1
+
w
a
x
∏
j
=
0
x
−
1
p
a
j
+
w
a
y
∏
j
=
0
y
−
1
p
a
j
+
∑
i
=
y
−
1
m
w
a
i
∏
j
=
0
i
−
1
p
a
j
R=\sum_{i=1}^{x-1} w_{ai} \prod_{j=0}^{i-1} + w_{ax} \prod_{j=0}^{x-1} p_{aj} + w_{ay} \prod_{j=0}^{y-1} p_{aj} + \sum_{i=y-1}^m w_{ai} \prod_ {j=0}^{i-1} p_{aj}
R=i=1∑x−1waij=0∏i−1+waxj=0∏x−1paj+wayj=0∏y−1paj+i=y−1∑mwaij=0∏i−1paj
若将y在前
R
′
=
∑
i
=
1
x
−
1
w
a
i
∏
j
=
0
i
−
1
+
w
a
y
∏
j
=
0
x
−
1
p
a
j
+
w
a
x
∏
j
=
0
x
−
1
p
a
j
+
∑
i
=
y
−
1
m
w
a
i
∏
j
=
0
i
−
1
p
a
j
R'=\sum_{i=1}^{x-1} w_{ai} \prod_{j=0}^{i-1} + w_{ay} \prod_{j=0}^{x-1} p_{aj} + w_{ax} \prod_{j=0}^{x-1} p_{aj} + \sum_{i=y-1}^m w_{ai} \prod_ {j=0}^{i-1} p_{aj}
R′=i=1∑x−1waij=0∏i−1+wayj=0∏x−1paj+waxj=0∏x−1paj+i=y−1∑mwaij=0∏i−1paj
所以 ,R与R’只有中间两项有区别。
为了化简,我们将R的第三项化为
w
a
y
p
a
x
∏
j
=
0
x
−
1
p
a
j
w_{ay}p_{ax}\prod_{j=0}^{x-1}p_{aj}
waypaxj=0∏x−1paj
R’也可以这样操作。
现在,将R-R’,可得
R
−
R
′
=
(
w
a
x
+
w
a
y
p
a
x
−
w
+
a
y
−
w
a
x
P
a
y
)
∏
j
=
0
x
−
1
p
a
j
R-R'=(w_{ax}+w_{ay}p_{ax}-w+{ay}-w_{ax}P_{ay})\prod_{j=0}^{x-1}p_{aj}
R−R′=(wax+waypax−w+ay−waxPay)j=0∏x−1paj
现假设a[x]在前更优,则R-R’>=0
又因
∏
j
=
0
x
−
1
p
a
j
>
=
0
\prod_{j=0}^{x-1}p_{aj}>=0
∏j=0x−1paj>=0
所以
w
a
x
(
1
−
p
a
y
)
−
w
a
y
(
1
−
p
a
x
)
>
=
0
w_{ax}(1-p_{ay})-w_{ay}(1-p_{ax})>=0
wax(1−pay)−way(1−pax)>=0
最后化简得
1
−
p
a
y
w
a
y
>
=
1
−
p
a
x
w
a
x
\frac{1-p_{ay}}{w_{ay}} >= \frac{1-p_{ax}}{w_{ax}}
way1−pay>=wax1−pax
这就是最后的公式,依据此公式,就能定义cmp函数,给选出的服务器排序。
接下来,是第二道,如何选出m个服务器。
这里使用的是dp算法,具体实现的思想是:
由公式得,排前面的会影响到后面的,但后面的不会影响前面的,所以可以从后往前推。
转移方程:dp[i][j]=max(dp[i+1][j],dp[i+1][j-1]*a[i].p+a[i].w);
下面是AC代码:
#include<bits/stdc++.h>
using namespace std;
const int MXN=1e5+7;
struct Node{
double p,w;
}a[MXN];
double dp[MXN][30];
bool cmp(Node x,Node y){
return (1-y.p)/y.w>=(1-x.p)/x.w;
}
int main(){
int n,m,q;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i].w;
}
for(int i=1;i<=n;i++){
cin>>q;
a[i].p=1.0*q/(1.0*10000);
}
sort(a+1,a+n+1,cmp);
for(int i=n;i>=1;i--){
for(int j=1;j<=min(m,n-i+1);j++){
dp[i][j]=max(dp[i+1][j],dp[i+1][j-1]*a[i].p+a[i].w);
}
}
printf("%.16lf\n",dp[1][m]);
}
谢谢观看!