解题思路

很明显的是个期望 $dp$。

先前想到 $dp[i][j]$ 表示第决策到第 $i$ 个时间段,已经进行了 $j$ 次申请,然后就没有然后了,因为这根本就没法转移啊,你又不知道前 $i-1$ 个时间段里哪一个时间段是申请换教室了的。所以此路不通,另寻他路---题解。天哪没有题解还咋做题啊

不妨再加入一维 $[0/1]$ 表示第 $j$ 个时间段有没有进行申请操作

那么就分为一下两种情况

  • 第 $i$ 个时间段申请了
  • 第 $i$ 个时间段没有申请

那么这两种状态分别是 $dp[i][j][1]$ 和 $dp[i][j][0]$,我们然后这个期望的话是距离乘以我走这段路的概率

算第一种情况 ( $dp[i][j][1]$ ) 包含的概率又分为下面的四种情况

  • 我从 $c[i-1]\rightarrow c[i]$,这时候概率是 $(1-k[i-1])\times (1-k[i])$
  • 我从 $c[i-1]\rightarrow d[i]$,这时候概率是 $(1-k[i-1])\times k[i]$
  • 我从 $d[i-1]\rightarrow c[i]$,这时候概率是 $k[i-1] \times (1-k[i])$
  • 我从 $d[i-1]\rightarrow d[i]$,这时候概率是 $k[i-1]\times k[i]$

再算第二种情况 ( $dp[i][j][0]$ ) 包含的概率又分为两种情况

  • 我从 $c[i-1]\rightarrow c[i]$,这时候概率是 $(1-k[i-1])$
  • 我从 $d[i-1]\rightarrow c[i]$,这时候概率是 $k[i-1]$

上述的大类情况仅为 $i-1$ 这个时间段进行了申请 ( $dp[i-1][j-1][1]\ or\ dp[i-1][j][1]$ )。

下面说另一种情况 ( $dp[i-1][j-1][0]\ or\ dp[i-1][j][0]$ )

  • 第一种情况 ( $dp[i][j][1]$ )

    • 我从 $c[i-1]\rightarrow c[i]$,概率是 $1-k[i]$
    • 我从 $c[i-1]\rightarrow d[i]$,概率是 $k[i]$
  • 第二种情况 ( $dp[i][j][0]$ )

    • 我从 $c[i-1]\rightarrow c[i]$,概率是 $1$

这就是所有的情况。

至于两个点之间的最短距离因为点的数量不超过 $300$,所以可以用 $\text{Floyd}$ 来处理

状态转移方程将上面的东西稍微整理一下就出来了,不过很长,所以不单独写了,看代码里的方程

附上代码

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn = , INF = 1e9;
int n, m, v, e, dis[maxn][maxn], c[maxn], d[maxn];
double k[maxn], dp[][][];
int main() {
scanf("%d%d%d%d", &n, &m, &v, &e);
for(int i=; i<=n; i++) scanf("%d", &c[i]);
for(int i=; i<=n; i++) scanf("%d", &d[i]);
for(int i=; i<=n; i++) cin >> k[i];
for(int i=; i<=v; i++)
for(int j=; j<=v; j++)
dis[i][j] = INF;
int x, y, z;
for(int i=; i<=e; i++) {
scanf("%d%d%d", &x, &y, &z);
dis[x][y] = dis[y][x] = min(z, dis[x][y]);
}
for(int s=; s<=v; s++)
for(int i=; i<=v; i++)
for(int j=; j<=v; j++)
if(dis[i][j] >= dis[i][s] + dis[s][j])
dis[i][j] = dis[i][s] + dis[s][j];
for (register int i = ; i <= v; i++)
dis[i][i] = dis[i][] = dis[][i] = ;
for (register int i = ; i <= n; i++)
for (register int j = ; j <= m; j++)
dp[i][j][] = dp[i][j][] = INF;
dp[][][] = dp[][][] = ;
for(int i=; i<=n; i++) {
dp[i][][] = dp[i - ][][] + dis[c[i - ]][c[i]];
for(int j=; j<=m; j++) {
dp[i][j][] = min (
dp[i-][j][] +
dis[c[i-]][c[i]] * (1.0-k[i-]) +
dis[d[i-]][c[i]] * k[i-],
dp[i-][j][] +
dis[c[i-]][c[i]]
);
dp[i][j][] = min (
dp[i-][j-][] +
dis[d[i-]][d[i]] * k[i-] * k[i] +
dis[d[i-]][c[i]] * k[i-] * (-k[i]) +
dis[c[i-]][d[i]] * (-k[i-]) * k[i] +
dis[c[i-]][c[i]] * (-k[i-]) * (-k[i]),
dp[i-][j-][] +
dis[c[i-]][d[i]] * k[i] +
dis[c[i-]][c[i]] * (-k[i])
);
}
}
double ans = 1e17;
for(int i=; i<=m; i++)
ans = min(ans, min(dp[n][i][], dp[n][i][]));
printf("%.2lf", ans);
}

「 Luogu P1850 」 换教室的更多相关文章

  1. 「NOIP2016」「P1850」 换教室(期望dp

    题目描述 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程. 在可以选择的课程中,有 2n2n 节课程安排在 nn 个时间段上.在第 ii(1 \leq i \leq n1≤ ...

  2. [Luogu 1850] noip16 换教室

    [Luogu 1850] noip16 换教室 好久没有更博客了,先唠嗑一会,花了两天的空闲时间大致做完了昨年的noip真题 虽然在经过思考大部分题目都可出解(天天爱跑步除外),但是并不知道考试时候造 ...

  3. 【洛谷P1850】换教室[2016NOIP提高组]

    换教室 期望DP 状态: f[i][j][0/1]表示前i节课 提交j个申请 第i个教室不申请/申请(为了确定当前教室,方便转移) 的最小期望 方程: f[i][j][0]=min(f[i-1][j] ...

  4. LOJ2360. 「NOIP2016」换教室【概率DP】【Floyed】【傻逼题】

    LINK 思路 先floyed出两点最短路 然后就可以直接\(dp_{i,j,0/1}\)表示前i节课选择换j节,换不换当前这一节的最小贡献 直接可以枚举上一次决策的状态计算概率进行统计就可以了 我变 ...

  5. [LOJ] #2360. 「NOIP2016」换教室

    期望DP #include<iostream> #include<cstring> #include<cstdio> #include<cctype> ...

  6. 「NOIP2016」换教室

    传送门 Description 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程. 在可以选择的课程中,有 $ 2n $ 节课程安排在 $ n $ 个时间段上.在第 $ i ...

  7. 洛谷P1850 [noip2016]换教室——期望DP

    题目:https://www.luogu.org/problemnew/show/P1850 注释掉了一堆愚蠢,自己还是太嫩了... 首先要注意选或不选是取 min 而不是 /2 ,因为这里的选或不选 ...

  8. 「 Luogu P1231 」 教辅的组成

    题目大意 有 $\text{N1}$ 本书 $\text{N2}$本练习册 $\text{N3}$本答案,一本书只能和一本练习册和一本答案配对.给你一些书和练习册,书和答案的可能的配对关系.问你最多可 ...

  9. Luogu 1580 [NOIP2016] 换教室

    先用Floyed做亮点之间的最短路,设计dp,记dp[i][j][0]为到第i节课,换了j次课,当前有没有换课达到的期望耗费体力最小值 方程(太长了还是看代码吧):dp[i][j][0]<-dp ...

随机推荐

  1. ffmpeg resize and scale

    ffmpeg缩小视频尺寸 | 楚盟博客 https://www.5yun.org/13126.html ffmpeg -i test.mp4 -s 480×360 out.mp4 常用分辨率: 108 ...

  2. luogu1966 火柴排队

    题目大意 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度.现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定义为: $\sum_{i=1}^n(a_i-b_i) ...

  3. ASP.NET调用存储过程并接收存储过程返回值

    ASP.NET调用存储过程并接收存储过程返回值 2010-08-02 11:26:17|  分类: C#|字号 订阅       2010年02月27日 星期六 23:52 假设表结构Create T ...

  4. 【Dairy】2016.11.5

    橘子洲一游

  5. android EditText如何使光标随着输入内容移动

    EditText 使光标随着输入内容移动的setSelection()

  6. 【POJ 2983】 Is the information reliable?

    [题目链接] 点击打开链接 [算法] 差分约束系统,SPFA判负环 [代码] #include <algorithm> #include <bitset> #include & ...

  7. SVN 打补丁 Apply Patch ***

    SVN补丁的方式,在不能连接服务器或者没有修改的权限,但是迫于形势,你又必须对这个文件进行修改,这时你就可以用Create patch创建补丁,然后把你创建的补丁发给项目人,或对此目录有写权限的工作人 ...

  8. JSP:目录

    ylbtech-JSP:目录 1.返回顶部   2.返回顶部   3.返回顶部   4.返回顶部   5.返回顶部     6.返回顶部   作者:ylbtech出处:http://ylbtech.c ...

  9. 14_activity四种状态说明

    之前讲过Servlet的生命周期.Servlet的生命周期相对来讲比较少,一共就那么几个方法.Activity的生命周期相对来讲还是比较多的. An activity is a single, foc ...

  10. PCB 帆软FineReport安装,布署,配置

    公司使用帆软FineReport做为报表平台工具也有一年多时间,而FineReport报表平台与Tomcat Web应用服务是站队在java阵营里,因为相信拥抱微软;.net未来发展会越来越好,所以对 ...