整体思路:
这节课换了教室的期望路程 = min(上节课换了教室的期望路程 + 上节课教室到这节课教室的期望路程, 上节课没换教室的期望路程+ 上节课教室到这节课教室的期望路程)
这节课没换教室的期望路程 = min(上节课换了教室的期望路程 + 上节课教室到这节课教室的期望路程,上节课没换教室的期望路程+ 上节课教室到这节课教室的期望路程)
上节课教室到这节课教室的期望路程 = 某一情况路程 * 这一情况发生的概率;
dp[i][j][0/1]第i节课换了j次这节课换或不换
细节:
初值,边界,
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n, m, v, e,c[2005],d[2005],bian[2005][2005];
double k[2005],f[2005][2005][2],ans = 1e18;
int main()
{
cin >> 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]);
}
memset(bian,0x3f3f3f3f3f,sizeof(bian));
for(int i = 1; i <= e; i++)
{
int x, y, w;
scanf("%d%d%d", &x, &y, &w);
bian[x][y] = min(w, bian[x][y]);
bian[y][x] = bian[x][y];
}
for(int i = 1; i <= v; i++)
bian[i][i] = 0;
for(int e = 1; e <= v; e++)
for(int i = 1; i <= v; i++)
for(int j = 1; j <= v; j++)
bian[i][j] = min(bian[i][j],bian[i][e] + bian[e][j]);
for(int i = 1; i <= n; i++)
for(int j = 0; j <= m; j++)
{
f[i][j][0] = f[i][j][1] = 1e30;
}
f[1][0][0] = f[1][1][1] = 0;
for(int i = 2; i <= n; i++)
{
int ha = min(i , m);
for(int j = 0; j <= ha; j++)
{
f[i][j][0] = min(f[i][j][0], f[i-1][j][0] + bian[c[i-1]][c[i]]);
f[i][j][0] = min(f[i][j][0], f[i-1][j][1] + bian[d[i-1]][c[i]] *k[i - 1] + bian[c[i-1]][c[i]] * (1.0 - k[i - 1]));
if(j >= 1)
{
f[i][j][1] = min(f[i-1][j-1][0] + bian[c[i-1]][d[i]] * k[i] + bian[c[i -1]][c[i]] * (1.0 - k[i]),f[i][j][1]);
f[i][j][1] = min(f[i][j][1],f[i-1][j-1][1] + bian[d[i-1]][d[i]] * k[i] * k[i-1] + bian[d[i-1]][c[i]] * k[i - 1] * (1.0 - k[i]) + bian[c[i-1]][d[i]] *(1.0 - k[i-1])*k[i] + bian[c[i-1]][c[i]] * (1.0 - k[i]) *(1.0 - k[i-1]));
}
}
}
for(int i = 0; i <= m; i++)
{
double t = min(f[n][i][0] , f[n][i][1]);
ans = min(ans, t);
}
printf("%0.2lf", ans);
return 0;
}