题解:
本蒟蒻第一次知道期望是啥意思。。很简单,就是全部概率*价值求和
感觉期望差不多都和DP有关吧
设
d
p
[
i
]
[
j
]
[
0
/
1
]
dp[i][j][0/1]
dp[i][j][0/1]表示选到第i节课,已经申请了换j节课,其中第i节选/不选的期望。
- d p [ i ] [ j ] [ 0 ] = { d p [ i − 1 ] [ j ] [ 0 ] + d i s [ c [ i − 1 ] [ c [ i ] ] d p [ i − 1 ] [ j ] [ 1 ] + d i s [ c [ i − 1 ] [ c [ i ] ] ∗ ( 1 − k [ i ] ) + d i s [ d [ i − 1 ] ] [ c [ i ] ] ∗ k [ i ] dp[i][j][0] = \left\{ \begin{array}{} dp[i - 1][j][0] + dis[c[i - 1][c[i]]\\ dp[i - 1][j][1] + dis[c[i - 1][c[i]] * (1 - k[i]) + dis[d[i - 1]][c[i]] * k[i]\\ \end{array} \right. dp[i][j][0]={dp[i−1][j][0]+dis[c[i−1][c[i]]dp[i−1][j][1]+dis[c[i−1][c[i]]∗(1−k[i])+dis[d[i−1]][c[i]]∗k[i]
- d p [ i ] [ j ] [ 1 ] = { d p [ i − 1 ] [ j ] [ 0 ] + d i s [ c [ i − 1 ] [ c [ i ] ] d p [ i − 1 ] [ j ] [ 1 ] + d i s [ c [ i − 1 ] [ c [ i ] ] ∗ ( 1 − k [ i ] ) + d i s [ d [ i − 1 ] ] [ c [ i ] ] ∗ k [ i ] dp[i][j][1] = \left\{ \begin{array}{} dp[i - 1][j][0] + dis[c[i - 1][c[i]]\\ dp[i - 1][j][1] + dis[c[i - 1][c[i]] * (1 - k[i]) + dis[d[i - 1]][c[i]] * k[i]\\ \end{array} \right. dp[i][j][1]={dp[i−1][j][0]+dis[c[i−1][c[i]]dp[i−1][j][1]+dis[c[i−1][c[i]]∗(1−k[i])+dis[d[i−1]][c[i]]∗k[i]
- d p [ i ] [ j ] [ 1 ] = { d p [ i − 1 ] [ j − 1 ] [ 0 ] + d i s [ c [ i − 1 ] ] [ d [ i ] ] ∗ k [ i ] + d i s [ c [ i − 1 ] ] [ c [ i ] ] ∗ ( 1.0 − k [ i ] ) d p [ i − 1 ] [ j − 1 ] [ 1 ] + d i s [ d [ i − 1 ] ] [ d [ i ] ] ∗ k [ i − 1 ] ∗ k [ i ] + d i s [ d [ i − 1 ] ] [ c [ i ] ] ∗ k [ i − 1 ] ∗ ( 1.0 − k [ i ] ) + d i s [ c [ i − 1 ] ] [ d [ i ] ] ∗ ( 1.0 − k [ i − 1 ] ) ∗ k [ i ] + d i s [ c [ i − 1 ] ] [ c [ i ] ] ∗ ( 1.0 − k [ i − 1 ] ) ∗ ( 1.0 − k [ i ] ) dp[i][j][1] = \left\{ \begin{array}{} dp[i - 1][j - 1][0] + dis[c[i - 1]][d[i]] * k[i] + dis[c[i - 1]][c[i]] * (1.0 - k[i])\\ dp[i - 1][j - 1][1] + dis[d[i - 1]][d[i]] * k[i - 1] * k[i] + dis[d[i - 1]][c[i]] * k[i - 1] * (1.0 - k[i])\\ +dis[c[i - 1]][d[i]] * (1.0 - k[i - 1]) * k[i] + dis[c[i - 1]][c[i]] * (1.0 - k[i - 1]) * (1.0 - k[i]) \\ \end{array} \right. dp[i][j][1]=⎩⎨⎧dp[i−1][j−1][0]+dis[c[i−1]][d[i]]∗k[i]+dis[c[i−1]][c[i]]∗(1.0−k[i])dp[i−1][j−1][1]+dis[d[i−1]][d[i]]∗k[i−1]∗k[i]+dis[d[i−1]][c[i]]∗k[i−1]∗(1.0−k[i])+dis[c[i−1]][d[i]]∗(1.0−k[i−1])∗k[i]+dis[c[i−1]][c[i]]∗(1.0−k[i−1])∗(1.0−k[i])
dis用floyd处理一下即可。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 2001;
int c[MAXN], d[MAXN];
double k[MAXN];
int dis[301][301];
double dp[MAXN][MAXN][2];
inline int read(){
int k = 0, f = 1; char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-') f = -1; ch = getchar();}
while(ch >= '0' && ch <= '9'){k = k*10 + ch - '0'; ch = getchar();}
return k * f;
}
int main(){
memset(dp, 0x43, sizeof(dp));
memset(dis, 0x3f, sizeof(dis));
int n = read(), m = read(), N = read(), M = read();
for(int i = 1; i <= n; i++){
c[i] = read();
}
for(int i = 1; i <= n; i++){
d[i] = read();
}
for(int i = 1; i <= n; i++){
scanf("%lf", &k[i]);
}
for(int i = 1; i <= N; i++){
dis[i][i] = 0;
}
for(int i = 1; i <= M; i++){
int a = read(), b = read(), l = read();
dis[a][b] = dis[b][a] = min(dis[a][b], l);
}
for(int K = 1; K <= N; K++){
for(int i = 1; i <= N; i++){
for(int j = 1; j < i; j++){
if(dis[i][j] > dis[i][K] + dis[K][j]){
dis[i][j] = dis[j][i] = dis[i][K] + dis[K][j];
}
}
}
}
dp[1][0][0] = dp[1][1][1] = 0;
for(int i = 2; i <= n; i++){
for(int j = 0; j <= min(i, m); j++){
dp[i][j][0] = min(
dp[i - 1][j][1] + (double)dis[c[i - 1]][c[i]] * (1.0 - k[i - 1])
+ (double)dis[d[i - 1]][c[i]] * k[i - 1],
dp[i - 1][j][0] + (double)dis[c[i - 1]][c[i]]
);
if(j){
dp[i][j][1] = min(
dp[i - 1][j - 1][0] + (double)dis[c[i - 1]][d[i]] * k[i]
+ (double)dis[c[i - 1]][c[i]] * (1.0 - k[i]),
dp[i - 1][j - 1][1] + (double)dis[d[i - 1]][d[i]] * k[i - 1] * k[i]
+ (double)dis[d[i - 1]][c[i]] * k[i - 1] * (1.0 - k[i])
+ (double)dis[c[i - 1]][d[i]] * (1.0 - k[i - 1]) * k[i]
+ (double)dis[c[i - 1]][c[i]] * (1.0 - k[i - 1]) * (1.0 - k[i])
);
}
}
}
double Ans = 2147483647;
for(int i = 0; i <= m; i++){
Ans = min(Ans, min(dp[n][i][0], dp[n][i][1]));
}
printf("%.2lf", Ans);
return 0;
}
//dp[i][j][0/1] 第i节课,第j次机会换/不换