【NOIP2016】换教室——期望dp

题目链接

其实还是要比d1t2的天天爱跑步简单一些的,期望dp的话也没考多难,就是转移方程可能稍微长一点。

考场上yyl说打个爆搜都能拿七十多分,%%%。

点数<=300,先跑一边floyd预处理出两两之间最短距离。

f[i][j]表示前i个时间段用了j次申请,再开一维0和1表示i这个时间段是否进行申请(0不申请1申请),那么

  x=f[i-1][j][0]+dis[ci[i]][ci[i-1]];
  y=f[i-1][j][1]+ki[i-1]*dis[ci[i]][di[i-1]]+(1-ki[i-1])*dis[ci[i]][ci[i-1]];

  f[i][j][0]=min(x,y).

而选择申请的状态转移方程就更长了:

  x=f[i-1][j-1][0]+ki[i]*dis[ci[i-1]][di[i]]+(1-ki[i])*dis[ci[i-1]][ci[i]];//前一个时间段不申请的期望
  y=f[i-1][j-1][1]+ki[i-1]*ki[i]*dis[di[i]][di[i-1]]+ki[i-1]*(1-ki[i])*dis[di[i-1]][ci[i]];//前一个时间段选择申请的期望
  y+=(1-ki[i-1])*ki[i]*dis[ci[i-1]][di[i]]+(1-ki[i-1])*(1-ki[i])*dis[ci[i-1]][ci[i]];//太长了所以写成两段
  f[i][j][1]=min(x,y);

最后答案就是min(f[n][0][0],min(f[n][i][0],f[n][i][1])(1<=i<=m))

代码:

 

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define mem(a,p) memset(a,p,sizeof(a))
 5 typedef double Cu;
 6 const int N=2005;
 7 int n,m,v,e;
 8 int ci[N],di[N];
 9 Cu dis[305][305];
10 Cu ki[N];
11 int read(){
12     int ans=0,f=1;char c=getchar();
13     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
14     while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();}
15     return ans*f;
16 }
17 Cu min(Cu x,Cu y){return x>y?y:x;}
18 Cu max(Cu x,Cu y){return x<y?y:x;}
19 void floyd(){
20     for(int k=1;k<=v;k++)
21         for(int i=1;i<=v;i++)
22             for(int j=1;j<=v;j++)
23             dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
24 }
25 Cu f[N][N][2];
26 int mins(int x,int y){return x>y?y:x;}
27 int main(){
28     n=read();m=read();v=read();e=read();
29     for(int i=1;i<=n;i++)ci[i]=read();
30     for(int j=1;j<=n;j++)di[j]=read();
31     for(int i=1;i<=n;i++)scanf("%lf",&ki[i]);
32     mem(dis,127);for(int i=1;i<=v;i++)dis[i][i]=0;
33     for(int i=1,a,b,c;i<=e;i++){
34         a=read();b=read();c=read();
35         dis[a][b]=dis[b][a]=min(c,dis[a][b]);
36     }
37     floyd();mem(f,127);
38     f[1][0][0]=f[1][1][1]=0;
39     for(int i=2;i<=n;i++){
40         for(int j=0;j<=mins(m,i);j++){
41             Cu x,y;
42             x=f[i-1][j][0]+dis[ci[i]][ci[i-1]];
43             y=f[i-1][j][1]+ki[i-1]*dis[ci[i]][di[i-1]]+(1-ki[i-1])*dis[ci[i]][ci[i-1]];
44             f[i][j][0]=min(x,y);
45             x=ki[i]*dis[ci[i-1]][di[i]]+(1-ki[i])*dis[ci[i-1]][ci[i]];
46             if(!j)continue;
47             x+=f[i-1][j-1][0];
48             y=f[i-1][j-1][1]+ki[i-1]*ki[i]*dis[di[i]][di[i-1]]+ki[i-1]*(1-ki[i])*dis[di[i-1]][ci[i]];
49             y+=(1-ki[i-1])*ki[i]*dis[ci[i-1]][di[i]]+(1-ki[i-1])*(1-ki[i])*dis[ci[i-1]][ci[i]];
50             f[i][j][1]=min(x,y);
51         }
52     }
53     Cu mni=f[n][0][0];
54     for(int i=1;i<=m;i++)mni=min(mni,min(f[n][i][0],f[n][i][1]));
55     printf("%.2f",mni);
56     return 0;
57 }
NOIP d1t3

 

posted @ 2017-10-17 18:22  Child-Single  阅读(231)  评论(0编辑  收藏  举报