题目链接
有n节课要上,每节课有固定教室c[i],有m次交换机会,可以将每节课教室换到d[i],有v个教室,e条边。问你依次上完课的最小期望
概率dp
X 表示总的距离,那么
X
=
∑
i
=
2
n
X
i
X = \sum_{i = 2}^n X_{i}
X=∑i=2nXi其中
X
i
X_{i}
Xi表示第i - 1节课到第i节课的距离
那么
E
(
X
)
=
∑
i
=
2
n
E
(
X
i
)
E(X) = \sum_{i = 2}^nE(X_{i})
E(X)=∑i=2nE(Xi),
设
f
[
i
]
[
j
]
[
0
1
]
f[i][j][0~1]
f[i][j][0 1]表示前i节课,交换了j次,0表示第i节课不交换,1表示第i节课交换
那么状态转移
#include <bits/stdc++.h>
using namespace std;
#define int long long
int mp[305][305];
int c[2005],d[2005];
double k[2005], f[2005][2005][2];
signed main()
{
int n,m,v,e;
cin >> n>> m>> v >> e;
for(int i = 1; i <= n ;i ++){
cin >> c[i];
}
for(int i = 1; i <= n; i ++){
cin >> d[i];
}
for(int i = 1; i <= n; i ++){
cin >> k[i];
}
for(int i = 1; i <= v; i ++){
for(int j = 1; j <= v; j ++){
mp[i][j] = 1e18;
}
mp[i][i] = 0;
}
for(int i = 1;i <= e; i ++){
int x, y,z;
cin >> x >> y >> z;
mp[x][y] = min(mp[x][y],z);
mp[y][x] = min(mp[y][x], z);
}
for(int k = 1; k <= v; k ++){
for(int i = 1; i <= v; i ++){
if( i != k)
for(int j = 1; j <= v; j ++){
mp[i][j] = min(mp[i][j], mp[i][k] + mp[k][j]);
}
}
}
for(int i = 1; i <= n; i ++){
for(int j = 0; j <= m ;j ++){
f[i][j][0] = f[i][j][1] = 1e18;
}
}
f[1][0][0] = f[1][1][1] = 0;
for(int i = 2; i <= n;i ++){
int x = min(i, m);
for(int j = 0; j <= x; j ++){//四种情况 两者都交换,一个交换,一个不交换,两者都不交换
//0表示 i 不交换,则 i - 1有 交换 ——>交换成功 + 交换失败 和不交换
f[i][j][0] = min(f[i][j][0], f[i - 1][j][0] + mp[c[i - 1]][c[i]]);//i - 1 和 i都不交换
f[i][j][0] = min(f[i][j][0], f[i - 1][j][1] + mp[c[i]][d[i - 1]]*(k[i - 1]) + mp[c[i - 1]][c[i]]*(1 - k[i - 1]));//i不交换 i- 1交换
if(j >= 1){
//1 表示i交换,则①i - 1有不交换,i ——>交换成功+交换失败,②i - 1 也交换,两者分别成功,失败
f[i][j][1] = min(f[i][j][1], f[i - 1][j - 1][0] + mp[c[i - 1]][d[i]]*(k[i]) + mp[c[i - 1]][c[i]]*(1 - k[i]));//
f[i][j][1] = min(f[i][j][1], f[i - 1][j - 1][1] + mp[d[i - 1]][d[i]]*k[i]*k[i - 1] + mp[c[i - 1]][c[i]]*(1 - k[i - 1])*(1 - k[i])
+ mp[c[i - 1]][d[i]]*(1 - k[i - 1])*k[i] + mp[d[i - 1]][c[i]]*(1 - k[i])*(k[i - 1]));
}
}
}
double ans = 1e18;
for(int i = 0; i <= m ;i ++){
ans = min(f[n][i][0], ans);
ans = min(f[n][i][1], ans);
}
printf("%.2f\n",ans);
}