ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

计蒜客 T2033 换教室

2021-07-26 23:04:49  阅读:269  来源: 互联网

标签:T2033 int 课间 这节 申请 教室 计蒜客 dp dis


题目链接:计蒜客 T2033 换教室

题目大意:

题解:
膜拜出题人!!!状态转移方程写到吐血。。。
膜拜出题人!!!状态转移方程写到吐血。。。
膜拜出题人!!!状态转移方程写到吐血。。。

首先通过\(Floyd\)计算所有教室间的最短距离。

设\(dp[i][j][0/1]\)表示前\(i\)节课申请了\(j\)次,第\(i\)节课是否申请的情况下耗费体力的期望的最小值。

一、首先考虑第\(i\)节课不申请的情况:

从两种情况转移而来:

  1. 上一节课没申请换课,那么课间从\(c[i-1]\)走到\(c[i]\);
  2. 上一节课申请换课了:
    (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. 上一节课没申请换课:
    (1) 这节课申请通过,那么课间从\(c[i-1]\)走到\(d[i]\);
    (2) 这节课申请没通过,那么课间从\(c[i-1]\)走到\(c[i]\)。
  2. 上一节课申请换课了:
    (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,int,课间,这节,申请,教室,计蒜客,dp,dis
来源: https://www.cnblogs.com/IzumiSagiri/p/15063678.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有