正题
题目大意
一张图,nnn次,每次在cic_ici上课,可以申请换课室到did_idi,成功概率kik_iki。求最短需要走的路径的期望长度
解题思路
先FlodyFlodyFlody预处理多源最短路,然后考虑dpdpdp
设fi,j,0/1f_{i,j,0/1}fi,j,0/1表示前iii次,已经申请了jjj次,这次是否申请了,的最短期望长度。
为了方便我们定义lc=ci−1,ld=di−1,nc=ci,nd=dilc=c_{i-1},ld=d_{i-1},nc=c_i,nd=d_ilc=ci−1,ld=di−1,nc=ci,nd=di
fi,j,0={fi−1,j,0+dislc,ncfi−1,j,1+ki−1∗disld,nc+(1−ki−1)∗dislc,ncf_{i,j,0}=\left\{\begin{matrix} f_{i-1,j,0}+dis_{lc,nc} & \\ f_{i-1,j,1}+k_{i-1}*dis_{ld,nc}+(1-k_{i-1})*dis_{lc,nc} \end{matrix}\right.fi,j,0={fi−1,j,0+dislc,ncfi−1,j,1+ki−1∗disld,nc+(1−ki−1)∗dislc,nc
而
fi,j,1={fi−1,j−1,0+ki∗dislc,nd+(1−ki)∗dislc,ncfi−1,j−1,1+ki−1∗ki∗disld,nd+(1−ki−1)∗ki∗dislc,nd+ki−1∗(1−ki)∗disldnc+(1−ki−1)∗(1−ki)∗dislc,ncf_{i,j,1}=\left\{\begin{matrix} f_{i-1,j-1,0}+k_i*dis_{lc,nd}+(1-k_i)*dis_{lc,nc} & \\ f_{i-1,j-1,1}+k_{i-1}*k_i*dis_{ld,nd}+(1-k_{i-1})*k_i*dis_{lc,nd}+ k_{i-1}*(1-k_i)*dis{ld}{nc}+(1-k_{i-1})*(1-k_i)*dis_{lc,nc} \end{matrix}\right.fi,j,1={fi−1,j−1,0+ki∗dislc,nd+(1−ki)∗dislc,ncfi−1,j−1,1+ki−1∗ki∗disld,nd+(1−ki−1)∗ki∗dislc,nd+ki−1∗(1−ki)∗disldnc+(1−ki−1)∗(1−ki)∗dislc,nc
codecodecode
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=2010;
int n,m,v,e,c[N],d[N],dis[N][N];
double k[N],f[N][N][2],mins;
int main()
{freopen("testdata.in","r",stdin);scanf("%d%d%d%d",&n,&m,&v,&e);for(int i=1;i<=n;i++)scanf("%d",&c[i]);for(int i=1;i<=n;i++)scanf("%d",&d[i]);for(int i=1;i<=n;i++)scanf("%lf",&k[i]);for(int i=1;i<=v;i++)for(int j=1;j<=v;j++)dis[i][j]=2147483647/3;for(int i=1;i<=e;i++){int x,y,w;scanf("%d%d%d",&x,&y,&w);dis[x][y]=dis[y][x]=min(dis[x][y],w);}for(int ks=1;ks<=v;ks++){dis[ks][ks]=0;for(int i=1;i<=v;i++)for(int j=1;j<=v;j++)if(dis[i][ks]+dis[ks][j]<dis[i][j])dis[i][j]=dis[i][ks]+dis[ks][j];}for(int i=0;i<=n;i++)for(int j=0;j<=m;j++)f[i][j][0]=f[i][j][1]=2147483647/3;f[1][1][1]=f[1][0][0]=0;for(int i=2;i<=n;i++){for(int j=0;j<=min(i,m);j++){f[i][j][0]=min(f[i-1][j][0]+dis[c[i-1]][c[i]],f[i-1][j][1]+k[i-1]*dis[d[i-1]][c[i]]+(1-k[i-1])*dis[c[i-1]][c[i]]);if(j){f[i][j][1]=min(f[i-1][j-1][0]+k[i]*dis[c[i-1]][d[i]]+(1-k[i])*dis[c[i-1]][c[i]],f[i-1][j-1][1]+k[i-1]*k[i]*dis[d[i-1]][d[i]]+(1-k[i-1])*k[i]*dis[c[i-1]][d[i]]+k[i-1]*(1-k[i])*dis[d[i-1]][c[i]]+(1-k[i-1])*(1-k[i])*dis[c[i-1]][c[i]]);}}}mins=2147483647;if(n==1) mins=0;for(int j=0;j<=m;j++)mins=min(mins,min(f[n][j][0],f[n][j][1]));printf("%0.2lf",mins);
}