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. hibernate框架学习笔记10:HQL查询详解

    HQL语句中不可以出现与表有关的内容,而是对象的属性 实体类(注意配置文件): package domain; import java.util.HashSet; import java.util.S ...

  2. 201621123062《java程序设计》第八周作业总结

    1. 本周学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. 思维导图: 2. 书面作业 2.1ArrayList代码分析 2.1.1 解释ArrayList的contains源代码 源 ...

  3. 雷云Razer Synapse2.0使用测评 -第二次作业

    雷蛇云驱动Razer Synapse2.0使用测评 雷蛇(Razer)是全球顶级游戏设备品牌之一,1998年由CEO Min-Liang Tan和Robert "Razerguy" ...

  4. 第201621123043 《Java程序设计》第13周学习总结

    1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 为你的系统增加网络功能(购物车.图书馆管理.斗地主等)-分组完成 系统还在创建中..... 为了让你 ...

  5. 《高级软件测试》web测试实践--12月31日记录

    今日的任务进度如上图所示.我们对华科软件学院和计算机学院的网站进行了对比分析,分析的角度包括基本功能分析.前端性能分析.用户调研等.在这里我们简单总结下我们得到的评测结果. 基本功能分析:计算机学院和 ...

  6. javascript参数传递中处理+号

    在传值过程中,如果+号也是值的一部分,那就需要对+号进行处理.否则+号会被过滤掉. 处理方式:只需要把js中传过去的+号替换成base64 编码 %2B encodeURI(str).replace( ...

  7. 微信支付get_brand_wcpay_request:fail

    最近做了微信支付功能,和后端一起踩坑中,微信一直报错:get_brand_wcpay_request:fail 出现该问题的原因: 1.生成的sign签名有问题 2.支付授权目录配置有问题 在经过仔细 ...

  8. SQLite 带你入门

    SQLite数据库相较于我们常用的Mysql,Oracle而言,实在是轻量得不行(最低只占几百K的内存).平时开发或生产环境中使用各种类型的数据库,可能都需要先安装数据库服务(server),然后才能 ...

  9. PHP处理上传文件

    HTML中使用type = 'file'类型的表单可以向服务器上传文件: 上传文件的表单必须在form中定义enctyp = 'multipart/form-data': HTML代码如下: < ...

  10. HttpClient 上传多个文件

    using (System.Net.Http.HttpClient client = new System.Net.Http.HttpClient()) { client.BaseAddress = ...