解题思路

很明显的是个期望 $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. YTU 2697: 血型统计

    2697: 血型统计 时间限制: 1 Sec  内存限制: 128 MB 提交: 405  解决: 164 题目描述 黑猫警长在犯罪现场发现了一些血迹,现已经委托检验机构确定了血型,需要统计各种血型的 ...

  2. 用C语言实现websocket服务器

    Websocket Echo Server Demo 背景 嵌入式设备的应用开发大都依靠C语言来完成,我去研究如何用c语言实现websocket服务器也是为了在嵌入式设备中实现一个ip camera的 ...

  3. Redis: Redis on Windows Setup

    ylbtech-Redis: Redis on Windows Setup 1.返回顶部 1. 2. 3. 4. 5. 6. 7. 8. 9. 2.返回顶部   3.返回顶部   4.返回顶部   5 ...

  4. gitlab gerrit jenkins CI/CD环境集成

    http://blog.csdn.net/williamwanglei/article/details/38498465

  5. poj 1286 Necklace of Beads【polya定理+burnside引理】

    和poj 2409差不多,就是k变成3了,详见 还有不一样的地方是记得特判n==0的情况不然会RE #include<iostream> #include<cstdio> us ...

  6. 使用printf和String.format格式化输出

    格式化输出 在哪些情况下使用格式化输出: 异常打印到日志中使用格式化输出有利于排查错误原因: printf格式化 示例: public class PrintfTest { public static ...

  7. 自动构造词法分析器的步骤——正规式转换为最小化DFA

    正规式-->最小化DFA 1.先把正则式-->NFA(非确定有穷自动机) 涉及一系列分解规则 2.再把NFA通过"子集构造法"-->DFA 通过子集构造法将NFA ...

  8. 思维题 HDOJ 5288 OO’s Sequence

    题目传送门 /* 定义两个数组,l[i]和r[i]表示第i个数左侧右侧接近它且值是a[i]因子的位置, 第i个数被选择后贡献的值是(r[i]-i)*(i-l[i]),每个数都枚举它的因子,更新l[i] ...

  9. Python 模拟postman上传文件

    最近工作需求:写的程序要用到python模拟postman操作,基于flask框架 代码很简单 但是百度一半天: import requests files = {'skFile': open(r&q ...

  10. excel poi 取单元格的值

    /** * 取单元格的值 * * @param cell 单元格对象 * @param treatAsStr 为true时,当做文本来取值 (取到的是文本,不会把“1”取成“1.0”) * @retu ...