BZOJ P4720[Noip2016]换教室____solution

题目太长不表

       <--无形传送,最为致命



学习一点数学期望的基础,预处理最短路,然后加上DP即可。(废话)

理解决策和结果的差别:

在这里每阶段的决策有两个:申请|不申请

结果有两个:换|不换

然而二者不是一一对应的关系;

而且决策意味着状态,结果只用于计算期望

为什么呢

因为答案要的就是对于某种决策组的期望

于是状态的设计应该是分为申请|不申请,

然后计算期望时讨论申请成不成功;

状态:f[i,j,0/1]讨论前i节课,申请j次,第三维=[第i节申请了]  

方程:

//f[i][j][0]=f[i-1][j][0]+dis(ci-1,ci)*ff[i-1][j][0]|f[i-1][j][1]+dis(ci-1,ci)*ff[i-1][j][1]+dis(di-1,ci)*ff[i-1][j][2]
//f[i][j][1]=f[i-1][j-1][0]+(dis(ci-1,di)*ki+dis[ci-1,ci]*(1-ki))*ff[i-1][j-1][0]|f[i-1][j-1][1]+(dis(ci-1,di)*ki+dis(ci-1,ci)*(1-ki))*ff[i-1][j-1][1]+(dis(di-1,di)*ki+dis(di-1,ci)*(1-ki))*ff[i-1][j-1][2]

|表示两者选一(当然是选小的)

ff表示与f(也就是期望)同步存在的概率

dis是最短路

剩下的如题

对了最短路记得判重边。

代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 using namespace std;
 5 double f[2010][2010][2];
 6 double ff[2010][2010][3];
 7 int dis[310][310];
 8 int c[2010],d[2010];
 9 double ki[2010];
10 int n,m,v,e;
11 int main()
12 {
13     int i,j,k,l;
14     double min=2147483600;
15     memset(dis,0x3f3f3f,sizeof(dis));
16     scanf("%d%d%d%d",&n,&m,&v,&e);
17     for(i=1;i<=n;i++)scanf("%d",&c[i]);
18     for(i=1;i<=n;i++)scanf("%d",&d[i]);
19     for(i=1;i<=n;i++)scanf("%lf",&ki[i]);
20     for(i=1;i<=e;i++){
21         scanf("%d%d%d",&j,&k,&l);
22         if(l<dis[j][k])
23             dis[j][k]=dis[k][j]=l;
24     }
25     for(k=1;k<=v;k++)
26         for(i=1;i<=v;i++)
27             for(j=1;j<=v;j++)
28                 if(i!=j)
29                     if (dis[i][j]>dis[i][k]+dis[k][j])
30                         dis[i][j]=dis[i][k]+dis[k][j];
31     for(i=1;i<=v;i++)dis[i][i]=0;
32     for(i=0;i<=n;i++)
33         for(j=0;j<=m;j++)
34             f[i][j][0]=f[i][j][1]=2147483600,ff[i][j][0]=ff[i][j][1]=ff[i][j][2]=2;
35     ff[1][1][1]=1-ki[1];ff[1][1][2]=ki[1];ff[1][0][0]=1;
36     f[1][1][1]=0;f[1][0][0]=0;
37     for(i=2;i<=n;i++)
38         for(j=0;j<=m;j++){
39             if(f[i-1][j][0]+dis[c[i-1]][c[i]]*ff[i-1][j][0]<f[i-1][j][1]+dis[c[i-1]][c[i]]*ff[i-1][j][1]+dis[d[i-1]][c[i]]*ff[i-1][j][2])
40                 f[i][j][0]=f[i-1][j][0]+dis[c[i-1]][c[i]]*ff[i-1][j][0],ff[i][j][0]=ff[i-1][j][0];
41             else
42                 f[i][j][0]=f[i-1][j][1]+dis[c[i-1]][c[i]]*ff[i-1][j][1]+dis[d[i-1]][c[i]]*ff[i-1][j][2],ff[i][j][0]=ff[i-1][j][1]+ff[i-1][j][2];
43             if(j>0){
44                 if(f[i-1][j-1][0]+(dis[c[i-1]][d[i]]*ki[i]+dis[c[i-1]][c[i]]*(1-ki[i]))*ff[i-1][j-1][0]<f[i-1][j-1][1]+(dis[c[i-1]][d[i]]*ki[i]+dis[c[i-1]][c[i]]*(1-ki[i]))*ff[i-1][j-1][1]+(dis[d[i-1]][d[i]]*ki[i]+dis[d[i-1]][c[i]]*(1-ki[i]))*ff[i-1][j-1][2])
45                     f[i][j][1]=f[i-1][j-1][0]+(dis[c[i-1]][d[i]]*ki[i]+dis[c[i-1]][c[i]]*(1-ki[i]))*ff[i-1][j-1][0],ff[i][j][1]=ff[i-1][j-1][0]*(1-ki[i]),ff[i][j][2]=ff[i-1][j-1][0]*ki[i];
46                 else
47                     f[i][j][1]=f[i-1][j-1][1]+(dis[c[i-1]][d[i]]*ki[i]+dis[c[i-1]][c[i]]*(1-ki[i]))*ff[i-1][j-1][1]+(dis[d[i-1]][d[i]]*ki[i]+dis[d[i-1]][c[i]]*(1-ki[i]))*ff[i-1][j-1][2],ff[i][j][1]=(ff[i-1][j-1][1]+ff[i-1][j-1][2])*(1-ki[i]),ff[i][j][2]=(ff[i-1][j-1][1]+ff[i-1][j-1][2])*ki[i];
48             }
49         }
50     for(i=0;i<=m;i++){
51         if(min>f[n][i][0])min=f[n][i][0];
52         if(min>f[n][i][1])min=f[n][i][1];
53     }
54     printf("%.2lf",min);
55     return 0;
56 }

现在想来,我还真是弱啊

 

posted @ 2017-08-16 10:32  F.W.Nietzsche  阅读(262)  评论(0编辑  收藏  举报