计蒜客 T2033 换教室
2021/7/26 23:05:43
本文主要是介绍计蒜客 T2033 换教室,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
题目链接:计蒜客 T2033 换教室
题目大意:
题解:
膜拜出题人!!!状态转移方程写到吐血。。。
膜拜出题人!!!状态转移方程写到吐血。。。
膜拜出题人!!!状态转移方程写到吐血。。。
首先通过\(Floyd\)计算所有教室间的最短距离。
设\(dp[i][j][0/1]\)表示前\(i\)节课申请了\(j\)次,第\(i\)节课是否申请的情况下耗费体力的期望的最小值。
一、首先考虑第\(i\)节课不申请的情况:
从两种情况转移而来:
- 上一节课没申请换课,那么课间从\(c[i-1]\)走到\(c[i]\);
- 上一节课申请换课了:
(1) 申请通过,那么课间从\(d[i-1]\)走到\(c[i]\);
(2) 申请没通过,那么课间从\(c[i-1]\)走到\(c[i]\)。
状态转移方程为:
\[dp[i][j][0]=min\{dp[i][j][0],dp[i−1][j][0]+dis[c[i−1]][c[i]],dp[i−1][j][1]+(1−p[i−1])∗dis[c[i−1]][c[i]]+p[i−1]∗dis[d[i−1]][c[i]]\} \]二、再考虑第\(i\)节课申请的情况:
还是从两种情况转移而来:
- 上一节课没申请换课:
(1) 这节课申请通过,那么课间从\(c[i-1]\)走到\(d[i]\);
(2) 这节课申请没通过,那么课间从\(c[i-1]\)走到\(c[i]\)。 - 上一节课申请换课了:
(1) 上节课申请通过,这节课申请通过,那么课间从\(d[i-1]\)走到\(d[i]\);
(2) 上节课申请没通过,这节课申请通过,那么课间从\(c[i-1]\)走到\(d[i]\)。
(3) 上节课申请通过,这节课申请没通过,那么课间从\(d[i-1]\)走到\(c[i]\);
(4) 上节课申请没通过,这节课申请没通过,那么课间从\(c[i-1]\)走到\(c[i]\)。
状态转移方程为:
\[dp[i][j][1]=min\{dp[i][j][1],dp[i−1][j−1][0]+p[i]∗dis[c[i−1]][d[i]]+(1−p[i])∗dis[c[i−1]][c[i]],dp[i−1][j−1][1]+p[i−1]∗p[i]∗dis[d[i−1]][d[i]]+p[i−1]∗(1−p[i])∗dis[d[i−1]][c[i]]+(1−p[i−1])∗p[i]∗dis[c[i−1]][d[i]]+(1−p[i−1])∗(1−p[i])∗dis[c[i−1]][c[i]]\} \]#include <iomanip> #include <iostream> using namespace std; #define INF 0x3f3f3f3f #define N 2010 #define M 310 double p[N], dis[M][M], dp[N][N][2]; int c[N], d[N], n, m, v, e; int main() { ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); 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 >> p[i]; } for (int i = 1; i <= v; ++i) { for (int j = 1; j <= v; ++j) { dis[i][j] = INF; } } for (int i = 1; i <= v; ++i) { dis[i][i] = 0; } for (int i = 1; i <= e; ++i) { int x, y; double z; cin >> x >> y >> z; dis[x][y] = dis[y][x] = min(dis[x][y], z); } for (int k = 1; k <= v; ++k) { // floyd 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 = 1; i <= n; i++) { for (int j = 0; j <= m; ++j) { dp[i][j][0] = dp[i][j][1] = INF; } } 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][j][0], dp[i - 1][j][0] + dis[c[i - 1]][c[i]]); dp[i][j][0] = min(dp[i][j][0], dp[i - 1][j][1] + (1 - p[i - 1]) * dis[c[i - 1]][c[i]] + p[i - 1] * dis[d[i - 1]][c[i]]); if (j) { dp[i][j][1] = min(dp[i][j][1], dp[i - 1][j - 1][0] + p[i] * dis[c[i - 1]][d[i]] + (1 - p[i]) * dis[c[i - 1]][c[i]]); dp[i][j][1] = min(dp[i][j][1], dp[i - 1][j - 1][1] + p[i - 1] * p[i] * dis[d[i - 1]][d[i]] + p[i - 1] * (1 - p[i]) * dis[d[i - 1]][c[i]] + (1 - p[i - 1]) * p[i] * dis[c[i - 1]][d[i]] + (1 - p[i - 1]) * (1 - p[i]) * dis[c[i - 1]][c[i]]); } } } double ans = INF; for (int i = 0; i <= m; ++i) { ans = min(ans, min(dp[n][i][1], dp[n][i][0])); } cout << fixed << setprecision(2) << ans; return 0; }
这篇关于计蒜客 T2033 换教室的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-19JAVA分布式id教程:轻松入门与实践
- 2024-11-19Java高并发教程:入门与实践指南
- 2024-11-19JAVA高并发直播教程:新手入门指南
- 2024-11-19Java高并发直播教程:入门与实践指南
- 2024-11-19Java微服务教程:初学者快速入门指南
- 2024-11-19JAVA微服务教程:新手入门的详细指南
- 2024-11-19Java微服务教程:从零开始搭建你的第一个微服务应用
- 2024-11-19Java项目开发教程:初学者必备指南
- 2024-11-19Java项目开发教程:新手快速入门指南
- 2024-11-19Java项目开发教程:零基础入门到实战