A题: Task Computing
原题链接:https://ac.nowcoder.com/acm/contest/33189/A
题目大意
有 nnn 台云服务器,第 iii 台具有计算效率 wiw_iwi 和传输效率 pip_ipi 。
对于一个计算任务,需要恰好在 mmm 台服务器上计算,设这 mmm 台服务器依次为 a1,a2,...,ama_1,a_2,...,a_ma1,a2,...,am 则最终计算效率为
∑i=1mwai∏j=0i=1paj\sum\limits_{i=1}^mw_{a_i}\prod\limits_{j=0}^{i=1}p_{a_j}i=1∑mwaij=0∏i=1paj
初始 a0=0,p0=1a_0=0,p_0=1a0=0,p0=1 。
求这 mmm 台服务器在最优排序下的最大计算效率。
题解
考虑在最优解中相邻的两台云服务器 ak,ak+1a_k,a_{k+1}ak,ak+1 ,设 ak=x,ak+1=ya_k=x,a_{k+1}=yak=x,ak+1=y (即 wak=wx,pak+1=pyw_{a_k}=w_x,p_{a_{k+1}}=p_ywak=wx,pak+1=py )。
则显然此时的总贡献为
W=∑i=1k−1wai∏j=0i−1paj+wx∏j=0k−1paj+wypx∏j=0k−1paj+∑i=k+2mwai∏j=0i−1pajW=\sum\limits_{i=1}^{k-1}w_{a_i}\prod\limits_{j=0}^{i-1}p_{a_j}+w_x\prod\limits_{j=0}^{k-1}p_{a_j}+w_yp_x\prod\limits_{j=0}^{k-1}p_{a_j}+\sum\limits_{i=k+2}^mw_{a_i}\prod\limits_{j=0}^{i-1}p_{a_j}W=i=1∑k−1waij=0∏i−1paj+wxj=0∏k−1paj+wypxj=0∏k−1paj+i=k+2∑mwaij=0∏i−1paj
(第三项中 wypx∏j=0k−1paj=wy∏j=0kpajw_yp_x\prod\limits_{j=0}^{k-1}p_{a_j}=w_ y\prod\limits_{j=0}^{k}p_{a_j}wypxj=0∏k−1paj=wyj=0∏kpaj )
若我们交换这两台云服务器,即令 ak=y,ak+1=xa_k=y,a_{k+1}=xak=y,ak+1=x 。
则显然此时的总贡献为
W′=∑i=1k−1wai∏j=0i−1paj+wy∏j=0k−1paj+wxpy∏j=0k−1paj+∑i=k+2mwai∏j=0i−1pajW'=\sum\limits_{i=1}^{k-1}w_{a_i}\prod\limits_{j=0}^{i-1}p_{a_j}+w_y\prod\limits_{j=0}^{k-1}p_{a_j}+w_xp_y\prod\limits_{j=0}^{k-1}p_{a_j}+\sum\limits_{i=k+2}^mw_{a_i}\prod\limits_{j=0}^{i-1}p_{a_j}W′=i=1∑k−1waij=0∏i−1paj+wyj=0∏k−1paj+wxpyj=0∏k−1paj+i=k+2∑mwaij=0∏i−1paj
做差可得
W−W′=(wx∏j=0k−1paj+wypx∏j=0k−1paj)−(wy∏j=0k−1paj+wxpy∏j=0k−1paj)=∏j=0k−1paj(wx+wypx−wy−wxpy)
\begin{aligned}
W-W'&=(w_x\prod\limits_{j=0}^{k-1}p_{a_j}+w_yp_x\prod\limits_{j=0}^{k-1}p_{a_j})-(w_y\prod\limits_{j=0}^{k-1}p_{a_j}+w_xp_y\prod\limits_{j=0}^{k-1}p_{a_j})\\
&=\prod\limits_{j=0}^{k-1}p_{a_j}(w_x+w_yp_x-w_y-w_xp_y)
\end{aligned}W−W′=(wxj=0∏k−1paj+wypxj=0∏k−1paj)−(wyj=0∏k−1paj+wxpyj=0∏k−1paj)=j=0∏k−1paj(wx+wypx−wy−wxpy)
因为在最优解中 ak=x,ak+1=ya_k=x,a_{k+1}=yak=x,ak+1=y ,故 W−W′≥0W-W'\ge0W−W′≥0 ,因为 ∏j=0k−1paj>0\prod\limits_{j=0}^{k-1}p_{a_j}>0j=0∏k−1paj>0 , 所以可得 wx+wypx−wy−wxpy≥0w_x+w_yp_x-w_y-w_xp_y\ge0wx+wypx−wy−wxpy≥0 ,根据该公式进行排序后,最优解肯定为云服务器的一个子序列(因为排序后换位不可能使答案更优了)。
关于偏序性的证明
wx+wypx−wy−wxpy≥0wx−wxpy≥wy−wypxwx(1−py)≥wy(1−px)1−pywy≥1−pxwx \begin{aligned} w_x+w_yp_x-w_y-w_xp_y&\ge0\\ w_x-w_xp_y&\ge w_y-w_yp_x\\ w_x(1-p_y)&\ge w_y(1-p_x)\\ \frac{1-p_y}{w_y}&\ge \frac{1-p_x}{w_x} \end{aligned}wx+wypx−wy−wxpywx−wxpywx(1−py)wy1−py≥0≥wy−wypx≥wy(1−px)≥wx1−px
该式左右两边分别只与 y,xy,xy,x 有关,显然具有传递性。
排序后,注意我们不能设状态 dpi,jdp_{i,j}dpi,j 表示前 iii 台云服务器中选择 jjj 台的最优效率,然后大力 dpdpdp 。考虑到对于式 ∑i=1mwai∏j=0i=1paj\sum\limits_{i=1}^mw_{a_i}\prod\limits_{j=0}^{i=1}p_{a_j}i=1∑mwaij=0∏i=1paj ,前面所选择的云服务器的 ppp 会对后面存在影响,因此存在后效性,不能直接 dpdpdp (同时我们也不能将 ppp 作为状态保存,复杂度不允许,而且浮点数也不方便保存)。
因此,我们设状态 dpi,jdp_{i,j}dpi,j 表示从第 iii 到nnn 台云服务器中选择 mmm 台的最优效率,此时后面所选择的云服务器不会对排在前面的云服务器造成影响,无后效性,可行。
易得转移式:
dpi,j=max{dpi+1,j(不选择第i台云服务器)dpi+1,j−1∗pi+wi(选择第i台云服务器)dp_{i,j}=max
\begin{cases}
dp_{i+1,j}&(不选择第i台云服务器)\\
dp_{i+1,j-1}*p_i+w_i&(选择第i台云服务器)
\end{cases}
dpi,j=max{dpi+1,jdpi+1,j−1∗pi+wi(不选择第i台云服务器)(选择第i台云服务器)
最终答案即为 dp1,mdp_{1,m}dp1,m 。
参考代码
#include<bits/stdc++.h>
using namespace std;
template<class T>inline void read(T&x){//快读
char c,last=' ';
while(!isdigit(c=getchar()))last=c;
x=c^48;
while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+(c^48);
if(last=='-')x=-x;
}
const int MAXN=1e5+5;
int n,m;
double dp[MAXN][25];
struct node{
int w;
double p;
}a[MAXN];
bool cmp(node a,node b){
return (1-a.p)/a.w<(1-b.p)/b.w;//注意sort时不允许有等号
}
int main()
{
read(n),read(m);
for(int i=1;i<=n;++i)read(a[i].w);
for(int i=1;i<=n;++i)cin>>a[i].p,a[i].p/=10000;
sort(a+1,a+n+1,cmp);
double ans=0;
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);
}
}
cout<<fixed<<setprecision(12)<<dp[1][m]<<'\n';
return 0;
}