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. SpringMVC之处理流程

    之前在学servlet时写过JavaWeb与Asp.net工作原理比较分析,那篇主要是大致描述了下servlet的工作流程,今天在家了解了下springmvc的工作原理,与asp.net中的mvc进行 ...

  2. C语言程序设计(基础)- 第2周作业

    1.阅读提问的智慧,要求仔细阅读链接内容,用自己的话描述你的收获,并举例子说明应该如何提问. 2.所有同学请在自己电脑上配置git.编译器(win10 系统的话就Dev-C++).翻译软件,十一回校后 ...

  3. SQL的介绍及MySQL的安装

    基础篇 - SQL 介绍及 MySQL 安装               SQL的介绍及MySQL的安装 课程介绍 本课程为实验楼提供的 MySQL 实验教程,所有的步骤都在实验楼在线实验环境中完成, ...

  4. Beta冲刺Day3

    项目进展 李明皇 今天解决的进度 完善了程序的运行逻辑(消息提示框等) 明天安排 前后端联动调试 林翔 今天解决的进度 向微信官方申请登录验证session以维护登录态 明天安排 继续完成维护登录态 ...

  5. linux下的Shell编程(3)shell里的流程控制

    if 语句 if 表达式如果条件命令组为真,则执行 then 后的部分.标准形式: if 判断命令,可以有很多个,真假取最后的返回值 then 如果前述为真做什么 [ # 方括号代表可选,别真打进去了 ...

  6. python入门(10)使用List和tuple

    python入门(10)使用List和tuple list Python内置的一种数据类型是列表:list.list是一种有序的集合,可以随时添加和删除其中的元素. 比如,列出班里所有同学的名字,就可 ...

  7. python全栈开发-hashlib模块(数据加密)、suprocess模块、xml模块

    一.hashlib模块 1.什么叫hash:hash是一种算法(3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法 ...

  8. Django 相关

    Web框架本质 其实所有的Web应用本质就是一个socket服务端,而用户的浏览器就是一个socket客户端.简单的socket代码如下: import socket sk = socket.sock ...

  9. SSM登陆注册

    package com.coingod.controller; import java.io.IOException;import java.io.PrintWriter;import java.ut ...

  10. Python入门之三元表达式\列表推导式\生成器表达式\递归匿名函数\内置函数

    本章目录: 一.三元表达式.列表推导式.生成器表达式 二.递归调用和二分法 三.匿名函数 四.内置函数 ================================================ ...