Description

对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程。

在可以选择的课程中,有 $2n$ 节课程安排在 $n$ 个时间段上。在第 $i$($1 \leq i \leq n$)个时间段上,两节内容相同的课程同时在不同的地点进行,其中,牛牛预先被安排在教室 $c_i$ 上课,而另一节课程在教室 $d_i$ 进行。

在不提交任何申请的情况下,学生们需要按时间段的顺序依次完成所有的 $n$ 节安排好的课程。如果学生想更换第 $i$ 节课程的教室,则需要提出申请。若申请通过,学生就可以在第 $i$ 个时间段去教室 $d_i$ 上课,否则仍然在教室 $c_i$ 上课。

由于更换教室的需求太多,申请不一定能获得通过。通过计算,牛牛发现申请更换第 $i$ 节课程的教室时,申请被通过的概率是一个已知的实数 $k_i$,并且对于不同课程的申请,被通过的概率是互相独立的。

学校规定,所有的申请只能在学期开始前一次性提交,并且每个人只能选择至多 $m$ 节课程进行申请。这意味着牛牛必须一次性决定是否申请更换每节课的教室,而不能根据某些课程的申请结果来决定其他课程是否申请;牛牛可以申请自己最希望更换教室的 $m$ 门课程,也可以不用完这 $m$ 个申请的机会,甚至可以一门课程都不申请。

因为不同的课程可能会被安排在不同的教室进行,所以牛牛需要利用课间时间从一间教室赶到另一间教室。

牛牛所在的大学有 $v$ 个教室,有 $e$ 条道路。每条道路连接两间教室,并且是可以双向通行的。由于道路的长度和拥堵程度不同,通过不同的道路耗费的体力可能会有所不同。 当第 $i$($1 \leq i \leq n-1$)节课结束后,牛牛就会从这节课的教室出发,选择一条耗费体力最少的路径前往下一节课的教室。

现在牛牛想知道,申请哪几门课程可以使他因在教室间移动耗费的体力值的总和的期望值最小,请你帮他求出这个最小值。

Input

从标准输入读入数据。

第一行四个整数 $n,m,v,e$。$n$ 表示这个学期内的时间段的数量;$m$ 表示牛牛最多可以申请更换多少节课程的教室;$v$ 表示牛牛学校里教室的数量;$e$表示牛牛的学校里道路的数量。

第二行 $n$ 个正整数,第 $i$($1 \leq i \leq n$)个正整数表示 $c_i$,即第 $i$ 个时间段牛牛被安排上课的教室;保证 $1 \le c_i \le v$。

第三行 $n$ 个正整数,第 $i$($1 \leq i \leq n$)个正整数表示 $d_i$,即第 $i$ 个时间段另一间上同样课程的教室;保证 $1 \le d_i \le v$。

第四行 $n$ 个实数,第 $i$($1 \leq i \leq n$)个实数表示 $k_i$,即牛牛申请在第 $i$ 个时间段更换教室获得通过的概率。保证 $0 \le k_i \le 1$。

接下来 $e$ 行,每行三个正整数 $a_j, b_j, w_j$,表示有一条双向道路连接教室 $a_j, b_j$,通过这条道路需要耗费的体力值是 $w_j$;保证 $1 \le a_j, b_j \le v$, $1 \le w_j \le 100$。

保证 $1 \leq n \leq 2000$,$0 \leq m \leq 2000$,$1 \leq v \leq 300$,$0 \leq e \leq 90000$。

保证通过学校里的道路,从任何一间教室出发,都能到达其他所有的教室。

保证输入的实数最多包含 $3$ 位小数。

Output

输出到标准输出。

输出一行,包含一个实数,四舍五入精确到小数点后恰好$2$位,表示答案。你的输出必须和标准输出完全一样才算正确。

测试数据保证四舍五入后的答案和准确答案的差的绝对值不大于 $4 \times 10^{-3}$。 (如果你不知道什么是浮点误差,这段话可以理解为:对于大多数的算法,你可以正常地使用浮点数类型而不用对它进行特殊的处理)

Sample Input

3 2 3 3
2 1 2
1 2 1
0.8 0.2 0.5
1 2 5
1 3 3
2 3 1

Sample Output

2.80

Sample Explanation

所有可行的申请方案和期望收益如下表:

申请更换教室的时间段 申请通过的时间段 出现的概率 耗费的体力值 耗费的体力值的期望
1.0 8 8.0
1 1 0.8 4 4.8
0.2 8
2 2 0.2 0 6.4
0.8 8
3 3 0.5 4 6.0
0.5 8
1、2 1、2 0.16 4 4.48
1 0.64 4
2 0.04 0
0.16 8
1、3 1、3 0.4 0 2.8
1 0.4 4
3 0.1 4
0.1 8
2、3 2、3 0.1 4 5.2
2 0.1 0
3 0.4 4
0.4 8

HINT

测试点 $n$ $m$ $v$ 特殊性质1 特殊性质2
1 $\leq1$ $\leq1$ $\leq300$ × ×
2 $\leq2$ $\leq0$ $\leq20$
3 $\leq1$ $\leq100$
4 $\leq2$ $\leq300$
5 $\leq3$ $\leq0$ $\leq20$
6 $\leq1$ $\leq100$ ×
7 $\leq2$ $\leq300$ ×
8 $\leq10$ $\leq0$
9 $\leq1$ $\leq20$ ×
10 $\leq2$ $\leq100$ ×
11 $\leq10$ $\leq300$
12 $\leq20$ $\leq0$ $\leq20$ ×
13 $\leq1$ $\leq100$ ×
14 $\leq2$ $\leq300$
15 $\leq20$ ×
16 $\leq300$ $\leq0$ $\leq20$ ×
17 $\leq1$ $\leq100$
18 $\leq2$ $\leq300$
19 $\leq300$ ×
20 $\leq2000$ $\leq0$ $\leq20$ ×
21 $\leq1$
22 $\leq2$ $\leq100$
23 $\leq2000$
24 $\leq300$
25

特殊性质1:图上任意两点 $a_i, b_i$ ($a_i \neq b_i$)间,存在一条耗费体力最少的路径只包含一条道路。

特殊性质2:对于所有的 $1 \leq i \leq n, k_i = 1$。

时间限制:$1\texttt{s}$

空间限制:$512\texttt{MB}$

题解

1、根据期望的线性特点可以知道总路程的期望等于每相邻两节课之间路程的期望相加,一条路径期望只和前后两次选课有关,所以我们可以$DP$来做;

2、预处理出任两点间的最短路;

3、设$f[i][j][k]$为前$i$节课用了$j$次换课机会,$k$取值$true$和$false$,代表第$i$节课有没有申请换课,$f$值是满足这些限制条件下的最大期望;

4、转移就直接枚举下一节课申不申请换课,根据前后这两节课是否申请,统计出不同的前后上课地点的概率,算出期望。

5、转移方程:

 //It is made by Awson on 2017.10.22
#include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Abs(x) ((x) < 0 ? (-(x)) : (x))
using namespace std;
const int N = ;
const int V = ;
const int INF = ~0u>>; int n, m, v, e, a, b, w;
int c[N+], d[N+];
int mp[V+][V+];
double k[N+];
double f[N+][N+][]; void floyd() {
for (int k = ; k <= v; k++)
for (int i = ; i <= v; i++) if (k != i)
for (int j = ; j <= v; j++) if (i != j && k != j)
mp[i][j] = Min(mp[i][j], mp[i][k]+mp[k][j]);
}
void work() {
scanf("%d%d%d%d", &n, &m, &v, &e);
for (int i = ; i <= n; i++) for (int j = ; j <= m; j++) f[i][j][] = f[i][j][] = INF;
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++) scanf("%lf", &k[i]);
memset(mp, /, sizeof(mp));
for (int i = ; i <= v; i++) mp[][i] = mp[i][i] = ;
for (int i = ; i <= e; i++) {
scanf("%d%d%d", &a, &b, &w);
mp[a][b] = mp[b][a] = Min(mp[a][b], w);
}
floyd();
f[][][] = ;
for (int i = ; i <= n; i++)
for (int j = ; j <= Min(m, i-); j++) {
f[i][j][] = min(f[i-][j][]+mp[c[i-]][c[i]], f[i-][j][]+k[i-]*mp[d[i-]][c[i]]+(-k[i-])*mp[c[i-]][c[i]]);
f[i][j+][] = min(f[i-][j][]+k[i]*mp[c[i-]][d[i]]+(-k[i])*mp[c[i-]][c[i]], f[i-][j][]+k[i]*k[i-]*mp[d[i-]][d[i]]+k[i]*(-k[i-])*mp[c[i-]][d[i]]+(-k[i])*k[i-]*mp[d[i-]][c[i]]+(-k[i-])*(-k[i])*mp[c[i-]][c[i]]);
}
double ans = INF;
for (int i = ; i <= m; i++) ans = min(ans, min(f[n][i][], f[n][i][]));
printf("%.2lf\n", ans);
}
int main() {
work();
return ;
}

[NOIp 2016]换教室的更多相关文章

  1. [BZOJ 4720][NOIP 2016] 换教室

    记得某dalao立了"联赛要是考概率期望我直播吃键盘"的$flag$然后就有了这道题233333 4720: [Noip2016]换教室 Time Limit: 20 Sec  M ...

  2. NOIP 2016 换教室 (luogu 1850 & uoj 262) - 概率与期望 - 动态规划

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

  3. NOIP 2016 换教室(期望dp)

    第一次做期望dp 并不知道每个阶段的期望之和就是整个的期望之和 所以一直卡在这 期望=代价*概率 然后注意只有申请了才算期望,否则按原来的. 这道题和前几个课程,申请的限制,当前选或不选,有关 这样很 ...

  4. 【NOIP】2016 换教室

    [算法]期望DP+floyd [题解]用floyd预处理最短距离. 注意重边与自环——图论双毒!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! QAQ 然后搞清楚方案和概率的问 ...

  5. Noip 2016 Day 1 & Day 2

    Day 1 >>> T1 >> 水题直接模拟AC: 考察三个知识点:1.你能不能编程 2.你会不会取模 3.你脑子抽不抽 然而第一次评测还是90,因为当模运算时 “ en ...

  6. Noip 2016

    Day1 思路: 大致是 把一个环拆成链, 找某个人无非是向右找或向左找(即对当前点加或减) 若加上要移动的位置后坐标大于总人数, 就把当前坐标减去总人数, 若减去要移动的位置后坐标小于0, 就把当前 ...

  7. BZOJ 4720 [Noip2016]换教室

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

  8. Bzoj 4720 换教室 (期望DP)

    刚发现Bzoj有Noip的题目,只会换教室这道题..... Bzoj 题面:Bzoj 4720 Luogu题目:P1850 换教室 大概是期望DPNoip极其友好的一道题目,DP不怎么会的我想到了,大 ...

  9. [Luogu 1850] noip16 换教室

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

随机推荐

  1. alpha-咸鱼冲刺day5

    一,合照 emmmmm.自然还是没有的. 二,项目燃尽图 三,项目进展 !!!QAQ可以做到跟数据库交互了!!!!先来撒花花!(然后继续甲板) 四,问题困难 日常啥都不会,百度真心玩一年. 还得自学n ...

  2. alpha-咸鱼冲刺day4

    一,合照 emmmmm.自然还是没有的. 二,项目燃尽图 三,项目进展 QAQ具体工作量没啥进展.但是前后端终于可以数据交互了!.. 四,问题困难 日常啥都不会,百度真心玩一年. 还得自学nodejs ...

  3. Twisted 延迟调用

    延迟(defer)是twisted框架中实现异步的编程体系,使程序设计可以采用事件驱动的机制 1.基本使用 defer可以看作一个管理回调函数的对象,可以向该对象添加需要的回调函数同时也可以指定该组函 ...

  4. PV & PVC - 每天5分钟玩转 Docker 容器技术(150)

    Volume 提供了非常好的数据持久化方案,不过在可管理性上还有不足. 拿前面 AWS EBS 的例子来说,要使用 Volume,Pod 必须事先知道如下信息: 当前 Volume 来自 AWS EB ...

  5. 《javascript设计模式与开发实践》阅读笔记(16)—— 状态模式

    状态模式 会区分事物内部的状态,事物内部状态的改变往往会带来事物的行为改变.比如电灯的开关是开还是关,在外界的表现就完全不同. 电灯例子 按照常规思路,实现一个电灯就是构造一个电灯类,然后指定一下它的 ...

  6. 【TensorFlow随笔】关于一个矩阵与多个矩阵相乘的问题

    问题描述: Specifically, I want to do matmul(A,B) where  'A' has shape (m,n)  'B' has shape (k,n,p) and t ...

  7. JAVA_SE基础——30.构造代码块

    黑马程序员入学blog...构造代码块作用:给所有的对象进行统一的初始化. 问题:要求每个小孩出生都会哭,这份代码有两个构造函数,如果需要每个小孩出生都要哭的话,那么就需要在不同的构造函数中都调用cr ...

  8. 2.sublime设置本地远程代码同步

    1.打开编辑器输入框(Ctrl+Shift+P),并执行 2.回车后输入sftp 3.回车个后,右键项目 4.修改配置信息,保存

  9. Netty事件监听和处理(下)

    上一篇 介绍了事件监听.责任链模型.socket接口和IO模型.线程模型等基本概念,以及Netty的整体结构,这篇就来说下Netty三大核心模块之一:事件监听和处理. 前面提到,Netty是一个NIO ...

  10. 新概念英语(1-25)Mrs. Smith's Kitchen

    What colour is the electric cooker? Mrs. Smith's Kitchen is small. There is a refrigerator in the ki ...