P1850 换教室

现在有一张图, 有 \(v <= 300\) 个节点

你需要从 \(c_{1}\) 到 \(c_{2}\) 到 \(c_{n} (n <= 2000)\)

现在你有 \(m\) 次机会把 \(c_{i}\) 换为 \(d_{i}\), 对于第 \(i\) 个, 成功的概率为 \(k_{i}\)

求走完整个路程的期望路径长度


错误日志: 作死赋值 \(double\) 用 \(memset\)


Solution

这是第一个有关期望的题呢

本题为期望 \(dp\) , 从上一个状态转移过来(听dalao说还有一种是计算本状态对后面状态的贡献)

具体来说, 这个状态可以由以上 \(n\) 个状态得到, 每个状态权值为 \(w_{i}\), 其中第 \(i\) 个状态到此状态的概率为 \(k_{i}\), 那么有此状态可以表示为 $$dp[now] = \sum_{i = 1}^{n}{w_{i} * k_{i}}$$

本题状态为:

\(dp[i][j][0/1]\) 代表选到第 \(i\) 门课用掉 \(j\) 次机会, 此次申请或不申请的期望值

所有转移详细记录在注释中

答案自然在 \(\min_{i = 0}^{m}{\min(dp[n][i][0], dp[n][i][1])}\)

Code

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#include<climits>
#define LL long long
#define REP(i, x, y) for(int (i) = (x);(i) <= (y);(i)++)
using namespace std;
int RD(){
int out = 0,flag = 1;char c = getchar();
while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
return flag * out;
}
const int maxn = 4019, maxv = 319;
int num, numc, numv, nr;
int map[maxv][maxv];
int c[maxn], d[maxn];
double k[maxn];
double dp[maxn][maxn][2];
void floyd(){
REP(i, 1, numv)map[i][i] = 0;
REP(k, 1, numv)REP(i, 1, numv)REP(j, 1, numv){
map[i][j] = min(map[i][j], map[i][k] + map[k][j]);
}
}
int dist(int x, int y){return map[x][y];}
void init(){
REP(i, 1, numv)REP(j, 1, numv)map[i][j] = 1e9;
REP(i, 1, num)REP(j, 0, numc)dp[i][j][0] = dp[i][j][1] = 1e9;
}
int main(){
num = RD(), numc = RD(), numv = RD(), nr = RD();
init();
REP(i, 1, num)c[i] = RD();
REP(i, 1, num)d[i] = RD();
REP(i, 1, num)cin>>k[i];
REP(i, 1, nr){
int u = RD(), v = RD(), dis = RD();
map[u][v] = min(map[u][v], dis);
map[v][u] = map[u][v];
}
floyd();
dp[1][0][0] = dp[1][1][1] = 0;//选或不选都为起点
REP(i, 2, num){
int m = min(numc, i);
REP(j, 0, m){//可以不申请换教室, 从0开始
dp[i][j][0] = min(//本次不申请
dp[i - 1][j][0] + dist(c[i], c[i - 1]),//上次不申请
dp[i - 1][j][1]//上次申请
+ dist(c[i], d[i - 1]) * k[i - 1]//申请成功
+ dist(c[i], c[i - 1]) * (1 - k[i - 1])//申请失败
);
if(!j)continue;
dp[i][j][1] = min(//本次申请
dp[i - 1][j - 1][0]//上次不申请
+ dist(d[i], c[i - 1]) * k[i]//本次成功
+ dist(c[i], c[i - 1]) * (1 - k[i]), //本次失败
dp[i - 1][j - 1][1]//上次申请
+ dist(c[i], c[i - 1]) * (1 - k[i]) * (1 - k[i - 1])//0->0
+ dist(d[i], c[i - 1]) * k[i] * (1 - k[i - 1])//0->1
+ dist(c[i], d[i - 1]) * (1 - k[i]) * k[i - 1]//1->0
+ dist(d[i], d[i - 1]) * k[i] * k[i - 1]//1->1
);
}
}
double ans = 100000019;
REP(i, 0, numc){
ans = min(ans, dp[num][i][0]);
ans = min(ans, dp[num][i][1]);
}
printf("%.2lf\n", ans);
return 0;
}

P1850 换教室的更多相关文章

  1. bzoj4720 / P1850 换教室(Floyd+期望dp)

    P1850 换教室 先用Floyd把最短路处理一遍,接下来就是重头戏了 用 f [ i ][ j ][ 0/1 ] 表示在第 i 个时间段,发出了 j 次申请(注意不一定成功),并且在这个时间段是否( ...

  2. 洛谷 P1850 换教室 解题报告

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

  3. 洛谷——P1850 换教室

    P1850 换教室 有 2n 节课程安排在 nn 个时间段上.在第 i个时间段上,两节内容相同的课程同时在不同的地点进行,其中,牛牛预先被安排在教室 $c_i$​ 上课,而另一节课程在教室 $d_i$ ...

  4. 洛谷 P1850 换教室

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

  5. Luogu P1850 换教室(期望dp)

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

  6. P1850 换教室 期望dp

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

  7. 洛谷P1850换教室

    题目传送门 理解题意:给定你一个学期的课程和教室数量以及教室之间的距离还有换教室成功的概率,求一个学期走的距离的期望最小值 题目是有够恶心的,属于那种一看就让人不想刷的题目...很明显的动规,但是那个 ...

  8. P1850 换教室[dp+期望]

    流下了不会概率的眼泪,由于不会概率,转移少写了点东西... 这个dp很简单,就是一个普通的线性dp加点期望.(刚开始写这道题时信笔写下) \(dp[0/1][i][j]\)表示到第\(i\)个时间段时 ...

  9. 【DP】【期望】$P1850$换教室

    链接 题目描述 有 \(2n\) 节课程安排在$ n$ 个时间段上.在第 \(i\)(\(1 \leq i \leq n\))个时间段上,两节内容相同的课程同时在不同的地点进行,其中,牛牛预先被安排在 ...

随机推荐

  1. 团队项目M1阶段个人反思

    郑培蕾: 作为项目的PM,我前期的工作还是有很大的缺陷的,因为没有在开发之前对项目进行一个合理的评估,所以后来分配任务的时候就很不科学, 而且任务分配的比较粗糙,没有细化到每个人每天应该做什么,这就导 ...

  2. Linux环境下Web环境搭建——Nginx

    1.安装依赖 yum -y install make gcc gcc-c++ ncurses-devel  ##编译环境 yum -y install zlib zlib-devel openssl ...

  3. Chapter 1 概述

    软件分为通用软件和应用软件,具有复杂.不可见和不断变化的特点:从出现到现在共经历了四个重要的发展阶段,但现在的软件发展依然存在着许多问题. 软件工程是采用工程的概念.原理.技术和方法来开发与维护软件, ...

  4. 图论 Kruskal算法 并查集

    #include<iostream> #include<cstring> #include<string> #include<cstdio> #incl ...

  5. PHP面试题一

    http://www.viphper.com/?p=28 1.用PHP打印出前一天的时间格式是2006-5-10 22:21:21(2分) $a = date("Y-m-d H:i:s&qu ...

  6. 开放地址法散列表ADT

    数据结构定义如下: typedef unsigned int Index; typedef Index Position; struct HashTbl; typedef struct HashTbl ...

  7. Beta版本测试第二天

    一. 每日会议 1. 照片 2. 昨日完成工作 登入界面的优化与注册界面的优化,之前的登入界面与注册界面没有设计好,使得登入界面与注册界面并不好看,这次对界面进行了优化.另外尝试了找回密码的功能. 3 ...

  8. JavaScript下的new操作符做了什么?

    可以参考知乎的一篇文章:https://zhuanlan.zhihu.com/p/23987456 参考网上其他人的文章,new发生了以下操作 参考MDN:https://developer.mozi ...

  9. 获取字符串中某个指定的子串出现的开始位置(CHARINDEX用法)

    CHARINDEX作用 写SQL语句我们经常需要判断一个字符串中是否包含另一个字符串,但是SQL SERVER中并没有像C#提供了Contains函数,不过SQL SERVER中提供了一个叫CHAEI ...

  10. js & Object reference bug

    js & Object reference bug bug object ref bug onClickButton (type = ``) { let { publishDate: publ ...