换教室
有n个课程,第i个课程你在\(c_i\)教室上课,同时又有一堂课在\(d_i\),现在你可以提交m个申请,在第i个课程到\(d_i\)上课,成功概率\(e_i\),现在给出v
个教室教室的图,询问最小的路径期望,\(1≤n≤2000,0≤m≤2000,1≤v≤300\)。
解
注意到点数很少,可以支持floyd,于是我们可以直接\(O(n^3)\)预处理最短路,而显然为最优化问题,所以对阶段进行转移更好,于是设\(f[i][j][0/1]\)表示到了第i个课程,已经申请了j个课程换教室,0表示当前课程换教室,反之,于是,设\(s[x][y]\)为x,y间的最短路,不难有
\[f[i][j][0]=min(f[i-1][j][0]+s[c[i]][c[i-1]],f[i-1][j][1]+
\]
\[s[c[i]][c[i-1]](1-e[i-1])+s[c[i]][d[i-1]]e[i-1])
\]
\[f[i][j][1]=min(f[i-1][j-1][0]+s[c[i]][c[i-1]](1-e[i])+s[d[i]][c[]i-1])e[i]
\]
\[,f[i-1][j-1][1]+s[c[i]][c[i-1]](1-e[i])(1-e[i-1])+s[c[i]][d[i-1]]
\]
\[(1-e[i-1])e[i]+s[d[i]][c[i-1]]e[i](1-e[i-1])+s[d[i]][d[i-1]]
\]
\[e[i]e[i-1])
\]
注意\(i\geq j\),\(f[1][0][0]=f[1][1][1]=0\),其余全为无限大,答案在第一维的最后一层找即可。
参考代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#define il inline
#define ri register
using namespace std;
int c[2001],d[2001],dis[301][301];
double dp[2001][2001][2],ki[2001];
template<class free>il free Min(free,free);
int main(){
int n,m,v,e,i,j,k;double ans(1e19);
scanf("%d%d%d%d",&n,&m,&v,&e);
for(i=1;i<=n;++i)scanf("%d",&c[i]);
for(i=1;i<=n;++i)scanf("%d",&d[i]);
for(i=1;i<=n;++i)scanf("%lf",&ki[i]);
memset(dis,6,sizeof(dis));for(i=1;i<=v;++i)dis[i][i]=0;
while(e--)scanf("%d%d%d",&i,&j,&k),dis[i][j]=dis[j][i]=min(dis[i][j],k);
for(k=1;k<=v;++k)
for(i=1;i<=v;++i)
for(j=1;j<=v;++j)
if(dis[i][k]+dis[k][j]<dis[i][j])
dis[i][j]=dis[i][k]+dis[k][j];
memset(dp,66,sizeof(dp)),dp[1][0][0]=dp[1][1][1]=0;
for(i=2;i<=n;++i){
dp[i][0][0]=dp[i-1][0][0]+dis[c[i]][c[i-1]];
for(j=1;j<=i&&j<=m;++j){
dp[i][j][0]=Min(dp[i-1][j][0]+dis[c[i]][c[i-1]],
dp[i-1][j][1]+dis[c[i]][c[i-1]]*
(1-ki[i-1])+dis[c[i]][d[i-1]]*ki[i-1]);
dp[i][j][1]=Min(dp[i-1][j-1][0]+dis[c[i]][c[i-1]]
*(1-ki[i])+dis[d[i]][c[i-1]]*ki[i],
dp[i-1][j-1][1]+dis[d[i]][d[i-1]]*ki[i]
*ki[i-1]+dis[d[i]][c[i-1]]*ki[i]*(1-ki[i-1])
+dis[c[i]][d[i-1]]*(1-ki[i])*ki[i-1]+
dis[c[i]][c[i-1]]*(1-ki[i])*(1-ki[i-1]));
}
}
for(i=0;i<=m;++i)ans=Min(ans,Min(dp[n][i][0],dp[n][i][1]));
printf("%.2lf",ans);
return 0;
}
template<class free>
il free Min(free a,free b){
return a<b?a:b;
}