啊。。。这个时间写博客,明天还要上学,整个人都不好了。。。
这是我写的第一道期望题hiahiahia。。。
题目大意就不说了QWQ
80分儿做法:先floyd,爆搜枚举哪些点取,求出答案,效率O(C(n,m)*n)。
100分:先floyd跑出两两点之间的距离,然后f[i][j][0/1]表示第i个时间,申请了j次换教室,0表示这个时间不申请,1表示这个时间申请,则有:
f[i+1][j][0]=min(f[i][j][0]+dis[a[i]][a[i+1]],f[i][j][1]+dis[b[i]][a[i+1]]*pro[i]+dis[a[i]][a[i+1]]*(1-pro[i]));
f[i+1][j+1][1]=min(f[i][j][1]+dis[a[i]][a[i+1]]*(1-pro[i])*(1-pro[i+1])+dis[b[i]][a[i+1]]*pro[i]*(1-pro[i+1])
+dis[a[i]][b[i+1]]*(1-pro[i])*pro[i+1]+dis[b[i]][b[i+1]]*pro[i]*pro[i+1],
f[i][j][0]+dis[a[i]][a[i+1]]*(1-pro[i+1])+dis[a[i]][b[i+1]]*pro[i+1]);
一开始freopen没删掉WA了好几次心态都崩了>_<
代码如下:

#include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> using namespace std; int a[2010],b[2010],dis[310][310],n,m,v,e,x,y,z; double pro[2010],f[2010][2010][2],ans; int main() { scanf("%d %d %d %d",&n,&m,&v,&e); for(int i=1;i<=n;i++)scanf("%d",&a[i]); for(int i=1;i<=n;i++)scanf("%d",&b[i]); for(int i=1;i<=n;i++)scanf("%lf",&pro[i]); for(int i=1;i<=v;i++)for(int j=1;j<=v;j++)if(i!=j)dis[i][j]=233333333; for(int i=1;i<=e;i++)scanf("%d%d%d",&x,&y,&z),dis[y][x]=dis[x][y]=min(dis[x][y],z); for(int k=1;k<=v;k++)for(int i=1;i<=v;i++)for(int j=1;j<=v;j++)dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]); for(int i=0;i<=n;i++)for(int j=0;j<=min(i,m);j++)f[i][j][0]=f[i][j][1]=23333333333.0; f[0][0][0]=0; for(int i=0;i<n;i++)for(int j=0;j<=min(i,m);j++) { f[i+1][j][0]=min(f[i][j][0]+dis[a[i]][a[i+1]],f[i][j][1]+dis[b[i]][a[i+1]]*pro[i]+dis[a[i]][a[i+1]]*(1-pro[i])); if(j==m)continue; f[i+1][j+1][1]=f[i][j][1]+dis[a[i]][a[i+1]]*(1-pro[i])*(1-pro[i+1])+dis[b[i]][a[i+1]]*pro[i]*(1-pro[i+1]); f[i+1][j+1][1]+=dis[a[i]][b[i+1]]*(1-pro[i])*pro[i+1]+dis[b[i]][b[i+1]]*pro[i]*pro[i+1]; f[i+1][j+1][1]=min(f[i+1][j+1][1],f[i][j][0]+dis[a[i]][a[i+1]]*(1-pro[i+1])+dis[a[i]][b[i+1]]*pro[i+1]); } ans=23333333333.0; for(int i=0;i<=m;i++) ans=min(ans,min(f[n][i][0],f[n][i][1])); printf("%.2lf ",ans); }