换教室

Time Limit: 20 Sec  Memory Limit: 512 MB
[Submit][Status][Discuss]

Description

Input

  第一行四个整数n,m,v,e。n表示这个学期内的时间段的数量;m表示牛牛最多可以申请更换多少节课程的教室;
  v表示牛牛学校里教室的数量;e表示牛牛的学校里道路的数量。
  第二行n个正整数,第i(1≤i≤n)个正整数表示c,,即第i个时间段牛牛被安排上课的教室;保证1≤ci≤v。
  第三行n个正整数,第i(1≤i≤n)个正整数表示di,即第i个时间段另一间上同样课程的教室;保证1≤di≤v。
  第四行n个实数,第i(1≤i≤n)个实数表示ki,即牛牛申请在第i个时间段更换教室获得通过的概率。保证0≤ki≤1。
  接下来e行,每行三个正整数aj,bj,wj,表示有一条双向道路连接教室aj,bj,通过这条道路需要耗费的体力值是Wj;
  保证通过学校里的道路,从任何一间教室出发,都能到达其他所有的教室。
  保证输入的实数最多包含3位小数。

Output

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

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

HINT

  1≤aj,bj≤v, 1≤wj≤100。
  1≤n≤2000, 0≤m≤2000, 1≤v≤300, 0≤e≤90000。

Main idea

  给定n个 原本教室ci 和 替换教室di,可以申请m次换课,如果 i 换课了则可以在di上课,否则在ci上课,每个教室之间有距离,求期望最小距离。

Solution

  很简单的期望DP,我们令 f[i][j][0\1] 表示 到了第 i 个状态,已经换了 j 次课,这次换不换课,然后分四种情况讨论一下即可。

Code

#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std; #define Road(a,b) (double)w[a][b]
#define tense(a,b) a = a<b ? a:b; const int ONE = ;
const double INF = 1e18; int n,m,v,e;
int x,y,z;
int c[ONE],d[ONE];
int w[][];
double f[ONE][ONE][],k[ONE];
double Ans; int get()
{
int res=,Q=;char c;
while( (c=getchar())< || c> )
if(c=='-')Q=-;
res=c-;
while( (c=getchar())>= && c<= )
res=res*+c-;
return res*Q;
} void Floyed()
{
for(int k=; k<=v; k++)
for(int i=; i<=v; i++)
for(int j=; j<=v; j++)
tense(w[i][j], w[i][k] + w[k][j]);
} double Eap10(int i)
{
return Road( c[i],c[i+] ) * (-k[i]) + Road( d[i],c[i+] ) * k[i];
} double Eap01(int i)
{
return Road( c[i],c[i+] ) * (-k[i+]) + Road( c[i],d[i+] ) * k[i+];
} double Eap11(int i)
{
return
Road( c[i], c[i+] ) * (-k[i]) * (-k[i+])
+ Road( c[i], d[i+] ) * (-k[i]) * k[i+]
+ Road( d[i], c[i+] ) * k[i] * (-k[i+])
+ Road( d[i], d[i+] ) * k[i] * k[i+];
} void DisApply(int i,int j)
{
if(j>=) f[i+][j][] = tense(f[i+][j][], f[i][j][] + Road( c[i],c[i+] ) );
if(j>=) f[i+][j][] = tense(f[i+][j][], f[i][j][] + Eap10(i) );
} void Apply(int i,int j)
{
if(j>=) f[i+][j][] = tense(f[i+][j][], f[i][j-][] + Eap01(i) );
if(j>=) f[i+][j][] = tense(f[i+][j][], f[i][j-][] + Eap11(i) );
} int main()
{
n = get(); m = get(); v = get(); e = get();
for(int i=; i<=n; i++) c[i] = get();
for(int i=; i<=n; i++) d[i] = get();
for(int i=; i<=n; i++) scanf("%lf", &k[i]); memset(w, , sizeof(w));
for(int i=; i<=v; i++) w[i][i] = ;
for(int i=; i<=e; i++)
{
x = get(); y = get(); z = get();
w[x][y] = min(w[x][y], z);
w[y][x] = min(w[y][x], z);
}
Floyed(); for(int i=; i<=n; i++)
for(int j=; j<=m; j++)
f[i][j][] = f[i][j][] = INF;
f[][][] = f[][][] = ; for(int i=; i<=n-; i++)
for(int j=; j<=m; j++)
DisApply(i,j), Apply(i,j); Ans = INF;
for(int j=; j<=m; j++)
{
tense(Ans, f[n][j][]);
tense(Ans, f[n][j][]);
} printf("%.2lf",Ans);
}

【BZOJ4720】【NOIP2016】换教室 [期望DP]的更多相关文章

  1. bzoj4720: [Noip2016]换教室(期望dp)

    4720: [Noip2016]换教室 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1294  Solved: 698[Submit][Status ...

  2. 【bzoj4720】[NOIP2016]换教室 期望dp

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

  3. 【bzoj4720】[Noip2016]换教室 期望dp+最短路

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

  4. JZYZOJ1457 [NOIP2016]换教室 期望dp 动态规划 floyd算法 最短路

    http://172.20.6.3/Problem_Show.asp?id=1457 我不知道为什么我倒着推期望只有80分,所以我妥协了,我对着题解写了个正的,我有罪. #include<cst ...

  5. 洛谷1850(NOIp2016) 换教室——期望dp

    题目:https://www.luogu.org/problemnew/show/P1850 状态里记录的是”上一回有没有申请“,而不是”上一回申请成功否“,不然“申请 j 次”就没法转移了. dou ...

  6. [NOIP2016]换教室 期望dp

    先弗洛伊德,然后把状态拆分遗传 #include<iostream> #include<cstdio> #include<cstring> #include< ...

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

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

  8. 换教室(期望+DP)

    换教室(期望+DP) \(dp(i,j,1/0)\)表示第\(i\)节课,申请了\(j\)次调换,这节课\(1/0\)调换. 换教室 转移的时候考虑: 上次没申请 这次也没申请 加上\(dis(fr[ ...

  9. 2018.08.30 bzoj4720: [Noip2016]换教室(期望dp)

    传送门 一道无脑的期望dp. 用f[i][j][0/1]表示前i堂课提出了j次申请且第i堂课没有(有)提出申请. 这样就可以状态转移了. 然而这题状态转移方程有点长... (主要是情况多... 代码: ...

随机推荐

  1. windows下cudnn的安装过程

    在CUDA安装成功之后,系统环境变量中会有如下两个变量显示:CUDA_PATH和CUDA_PATH_8 在安装完CUDA之后,到官网下载与其版本对应的CUDNN        下载地址:https:/ ...

  2. LintCode-376.二叉树的路径和

    二叉树的路径和 给定一个二叉树,找出所有路径中各节点相加总和等于给定 目标值 的路径. 一个有效的路径,指的是从根节点到叶节点的路径. 样例 给定一个二叉树,和 目标值 = 5: 返回: [      ...

  3. <Android>tab选项卡

    1.继承TabActivity实现 a)         在布局文件中使用FrameLayout列出Tab组件及Tab中的内容组件 b)        Activity要继承TabActivity c ...

  4. DBGrid相关技术整理

    DBGrid相关技术整理: 注:对于DBGrid相关属性.方法的学习融入到技术整理过程中 一,多选 设置属性: Options->dgMultiSelect = True; ->dgRow ...

  5. SpringBoot使用servletAPI与异常处理

    工程结构: 主方法类: package com.boot.servlet.api.bootservlet; import org.springframework.boot.SpringApplicat ...

  6. C++基础知识(一)

    C++中头文件中class的两个花括号后面要加上分号,否则会出现很多的莫名奇妙的错误. 一. 每一个C++程序(或者由多个源文件组成的C++项目)都必须包含且只有一个main()函数.对于预处理指令, ...

  7. 转:使用 python Matplotlib 库 绘图 及 相关问题

     使用 python Matplotlib 库绘图      转:http://blog.csdn.net/daniel_ustc/article/details/9714163 Matplotlib ...

  8. ARC077D 11 组合数

    ---题面--- 题解: 做这道题的时候zz了,,,, 写了个很复杂的式子,然而后面重新想就发现很简单了. 考虑用总的情况减去重复的. 假设唯一重复的两个数的位置分别是l和r,那么唯一会导致重复的方案 ...

  9. BZOJ1061:[NOI2008]志愿者招募——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=1061 https://www.luogu.org/problemnew/show/P3980 申奥 ...

  10. 51NOD 1773:A国的贸易——题解

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1773 参考1:FWT讲解 https://www.cnblogs.com ...