【niop2016】【luogu1600】换教室[概率dp]

luogu1600

假设{ Bn | n = 1, 2, 3, ... } 是一个概率空间的有限或者可数无限的分割,且每 个集合 Bn 是一个可测集合,则对任意事件 A 有全概率公式:

一下来自  贼清晰!简直是一朵清奇的白莲花

  • f[i][j][0/1]表示前i个时间点,共申请了j次,第i个时间点否/是进行了申请。
  • dis[a][b]表示a教室->b教室的距离
  • c[i]表示默认的教室
  • d[i]表示更换后的教室
  • k[i]表示第i个教室申请成功的概率

分类讨论主要分成两大类,4小类,最后分成9个小项进行考虑。

  • 一、当前教室没有申请

    • 如果前一教室有申请: f[i][j][0]=min(f[i−1][j][1]f[i][j][0]=min(f[i-1][j][1]f[i][j][0]=min(f[i−1][j][1]

      • (1)成功:+k[i−1]∗dis[d[i−1]][c[i]]+k[i-1]*dis[d[i-1]][c[i]]+k[i−1]∗dis[d[i−1]][c[i]]
      • (2)失败:+(1−k[i−1])∗dis[c[i−1]][c[i]]+(1-k[i-1])*dis[c[i-1]][c[i]]+(1−k[i−1])∗dis[c[i−1]][c[i]]
    • 如果前一教室没有申请:,f[i−1][j][0],f[i-1][j][0],f[i−1][j][0],一定是前后均失败:+dis[c[i−1]][c[i]])+dis[c[i-1]][c[i]])+dis[c[i−1]][c[i]])
  • 二、当前教室有申请
  • 如果前一教室有申请:f[i][j][1]=min(f[i−1][j−1][1]f[i][j][1]=min(f[i-1][j-1][1]f[i][j][1]=min(f[i−1][j−1][1]
    • (1)前后均成功:+k[i−1]∗k[i]∗dis[d[i−1]][d[i]]+k[i-1]*k[i]*dis[d[i-1]][d[i]]+k[i−1]∗k[i]∗dis[d[i−1]][d[i]]
    • (2)前成功、后失败:+k[i−1]∗(1−k[i])∗dis[d[i−1]][c[i]]+k[i-1]*(1-k[i])*dis[d[i-1]][c[i]]+k[i−1]∗(1−k[i])∗dis[d[i−1]][c[i]]
    • (3)前失败、后成功:+(1−k[i−1])∗k[i]∗dis[c[i−1]][d[i]]+(1-k[i-1])*k[i]*dis[c[i-1]][d[i]]+(1−k[i−1])∗k[i]∗dis[c[i−1]][d[i]]
    • (4)前后均失败:+(1−k[i−1])∗(1−k[i])∗dis[c[i−1]][c[i]]+(1-k[i-1])*(1-k[i])*dis[c[i-1]][c[i]]+(1−k[i−1])∗(1−k[i])∗dis[c[i−1]][c[i]]
  • 如果前一教室没有申请:,f[i−1][j−1][0],f[i-1][j-1][0],f[i−1][j−1][0]
    • (1)后成功:+k[i]∗dis[c[i−1]][d[i]]+k[i]*dis[c[i-1]][d[i]]+k[i]∗dis[c[i−1]][d[i]]
    • (2)后失败:+(1−k[i])∗dis[c[i−1]][c[i]])+(1-k[i])*dis[c[i-1]][c[i]])+(1−k[i])∗dis[c[i−1]][c[i]])
代码

 1 /*
 2 id:gww
 3 language:C--
 4
 5 */
 6 #include<bits/stdc++.h>
 7 using namespace std;
 8 const int inf=0x3f3f3f3f;
 9 const int N=2000+100,V=300+100;
10 int n,m,v,e;
11 int c[N],d[N],co[V][V];
12 //教室 可换教室 消耗体力值
13 double k[N],f[N][N][2],ans=inf;
14 inline int rd()
15 {
16     int x=0,w=0;char ch=0;
17     while(!isdigit(ch)) w|=ch==‘-‘,ch=getchar();
18     while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
19     return w?-x:x;
20 }
21
22
23 void Floyd()//处理出任意教室之间消耗最小体力值
24 {
25     for (int kk=1;kk<=v;kk++)//中转点
26     for (int a=1;a<=v;a++)
27     for (int b=1;b<a;b++)
28     if (co[a][b]>co[a][kk]+co[kk][b])
29     co[b][a]=co[a][b]=co[a][kk]+co[kk][b];
30 }
31
32 void lxy()
33 {
34     for (int i=2;i<=n;i++)//时间段
35         for (int j=0;j<=m;j++)//申请数
36         {
37             double a=k[i-1],b=k[i];
38             int x=co[d[i-1]][c[i]],y=co[d[i-1]][d[i]],z=co[c[i-1]][c[i]],w=co[c[i-1]][d[i]];
39             //前1后0 前后均成功 前后均失败 前0后1
40             f[i][j][0]= min(f[i-1][j][1]+a*x+ (1-a)*z, f[i-1][j][0] +z);//当前时间未申请
41             if(j)//当前时间段申请了
42             f[i][j][1]=min(f[i-1][j-1][0]+b*w+(1-b)*z,f[i-1][j-1][1]+a*b*y+a*(1-k[i])*x+(1-a)*b*w+(1-a)*(1-b)*z);
43             // 前一段未申请   前一段申请了
44         }
45 }
46
47 int main()
48 {
49     //memset(dis,inf,sizeof(dis));//初始化赋极大值
50     n=rd(),m=rd(),v=rd(),e=rd();
51     for (int i=1;i<=n;i++) c[i]=rd();
52     for (int i=1;i<=n;i++) d[i]=rd();
53     for (int i=1;i<=n;i++) scanf("%lf",&k[i]);
54     for (int i=1;i<=v;i++)
55     for (int j=1;j<i;j++)
56     co[j][i]=co[i][j]=inf;
57     for (int i=1;i<=e;i++)
58     {
59         int x=rd(),y=rd(),w=rd();
60         co[x][y]=co[y][x]=min(co[x][y],w);
61     }
62     Floyd();
63     for (int i=1;i<=n;i++)
64     for (int j=0;j<=m;j++)
65     f[i][j][0]=f[i][j][1]=inf;
66     f[1][0][0]=0;f[1][1][1]=0;//初始化
67     lxy();
68     for (int i=0;i<=m;i++)
69     ans=min(ans,min(f[n][i][1],f[n][i][0]));
70     printf("%.2lf",ans);
71     return 0;
72 }

100昏 概率dp

原文地址:https://www.cnblogs.com/lxyyyy/p/10380941.html

时间: 2024-08-30 05:19:32

【niop2016】【luogu1600】换教室[概率dp]的相关文章

P1850 换教室 概率dp

其实说是概率dp,本质上和dp没什么区别,就是把所有可能转移的情况全枚举一下就行了,不过dp方程确实有点长... ps:这个题的floyed我竟然之前写跪了... 题目: 题目描述 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程. 在可以选择的课程中,有 2n2n2n 节课程安排在 nnn 个时间段上.在第 iii(1≤i≤n1 \leq i \leq n1≤i≤n)个时间段上,两节内容相同的课程同时在不同的地点进行,其中,牛牛预先被安排在教室 cic_ici? 上课

bzoj4720 换教室 概率dp

链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4720 重述题意:有n节课,每节课有两个教室同时授课,可以改变m次教室,每次改变有独立的成功率,每次交换教室需要消耗一定体力,求出最低期望消耗体力.(教室数量<=200) 我们可以观察到,教室数量很少,而每次我们都需要处理出两个教室之间的距离,涉及到多个源点,因此我们选择floyd预处理每两个教室之间距离,这是O(n3)的枚举. 随后,我们对每一个状态进行动态规划.设数组f[i][j][k]为

noip2016 换教室 概率+dp

非常好的dp,继续加油练习dp啊 #include<bits/stdc++.h> #define rep(i,x,y) for(register int i=x;i<=y;i++) using namespace std; const int N=2e3+50; const double inf=1e8+5; const int V=305; int n,m,v,e,c[N],d[N],g[V][V]; double k[N],f[N][N][2],ans; inline int rea

Luogu P1850 换教室(期望dp)

P1850 换教室 题意 题目描述 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程. 在可以选择的课程中,有\(2n\)节课程安排在\(n\)个时间段上.在第\(i(1\leq i\leq n)\)个时间段上,两节内容相同的课程同时在不同的地点进行,其中,牛牛预先被安排在教室\(c_i\)上课,而另一节课程在教室\(d_i\)进行. 在不提交任何申请的情况下,学生们需要按时间段的顺序依次完成所有的 nn 节安排好的课程.如果学生想更换第\(i\)节课程的教室,则需要提

P1850 换教室——期望DP

题目描述 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程. 在可以选择的课程中,有 2n2n2n 节课程安排在 nnn 个时间段上.在第 iii(1≤i≤n1 \leq i \leq n1≤i≤n)个时间段上,两节内容相同的课程同时在不同的地点进行,其中,牛牛预先被安排在教室 cic_ici? 上课,而另一节课程在教室 did_idi? 进行. 在不提交任何申请的情况下,学生们需要按时间段的顺序依次完成所有的 nnn 节安排好的课程.如果学生想更换第 iii 节课程的

NOIp2016Day1T3--换教室--概率dp+floyd

题目描述 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程. 在可以选择的课程中,有 2n 节课程安排在 n 个时间段上.在第i个时间段上,两节内容相同的课程同时在不同的地点进行,其中,牛牛预先被安排在教室ci上课,而另一节课程在教室 di行. 在不提交任何申请的情况下,学生们需要按时间段的顺序依次完成所有的 n 节安排好的课程.如果学生想更换第 i节课程的教室,则需要提出申请.若申请通过,学生就可以在第 i 个时间段去教室 d?i?? 上课,否则仍然在教室 c?i??

【NOIP2016】换教室(DP,期望)

题意: 对于刚上大学的牛牛来说, 他面临的第一个问题是如何根据实际情况中情合适的课程. 在可以选择的课程中,有2n节课程安排在n个时间段上.在第 i ( 1≤ i≤n)个时同段上, 两节内容相同的课程同时在不同的地点进行, 其中, 牛牛预先被安排在教室 ci上课, 而另一节课程在教室 di进行. 在不提交任何申请的情况下,学生们需要按时间段的顺序依次完成所有的n节安排好的课程.如果学生想更换第i节课程的教室,则需要提出中情.若申请通过,学生就可以在第 i个时间段去教室 di上课, 否则仍然在教室

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

http://172.20.6.3/Problem_Show.asp?id=1457 我不知道为什么我倒着推期望只有80分,所以我妥协了,我对着题解写了个正的,我有罪. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #include<iostream> 6 #include<queue> 7 using namespac

期望与概率dp

概率与期望dp 定义: 概率:事件A发生的可能性,计作P(A) 期望:事件A结果的平均大小,记住E(x) ? E(x)=每种结果的大小与其概率的乘积的和 注意计算概率时需要考虑是否要用容斥原理 期望dp时注意有时要用倒序枚举 其实本质和其他的dp没什么区别 例题 概率充电器 题面 题意:n个充电元件由n-1条导线连通,每个充电原件自身是否直接充电以及每条导线是否导电都由概率决定,求进入充电状态的元件个数的期望 1<=n<=500000 树形换根概率dp,注意使用容斥原理 第一遍dfs:计算出f