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 namespace std;
 8 const int maxn=2010;
 9 int t,k,n,m;
10 int c[2][maxn]={};
11 int dis[310][310]={};
12 int vis[maxn]={};
13 double f[maxn][maxn][2];
14 double ke[maxn]={};
15 int main(){
16     //freopen("wtf.in","r",stdin);
17     scanf("%d%d%d%d",&t,&k,&n,&m);
18     int x,y,v;
19     for(int i=1;i<=t;i++){
20         scanf("%d",&c[0][i]);
21     }
22     for(int i=1;i<=t;i++){
23         scanf("%d",&c[1][i]);
24     }
25     for(int i=1;i<=t;i++){
26         scanf("%lf",&ke[i]);
27     }
28     memset(dis,63,sizeof(dis));
29     for(int i=1;i<=n;i++) dis[i][i]=0;
30     for(int i=1;i<=m;i++){
31         scanf("%d%d%d",&x,&y,&v);
32         dis[x][y]=min(dis[x][y],v);
33         dis[y][x]=dis[x][y];
34     }
35     for(int i=1;i<=n;i++){
36         for(int j=1;j<=n;j++){
37             if(i==j)continue;
38             for(int w=1;w<=n;w++){
39                 if(dis[j][i]+dis[i][w]<dis[j][w]){
40                     dis[j][w]=dis[j][i]+dis[i][w];
41                 }
42             }
43         }
44     }
45     for(int i=1;i<=n;i++) dis[i][0]=dis[0][i]=0;
46     for(int i=0;i<=t;i++){
47         for(int j=0;j<=k;j++){
48             f[i][j][1]=20000000000.0;
49             f[i][j][0]=20000000000.0;
50         }
51     }double ans=f[0][0][0];
52     f[1][0][0]=f[1][1][1]=0;
53     for(int i=2;i<=t;i++){
54         int ma=min(i,k);
55         f[i][0][0]=f[i-1][0][0]+dis[c[0][i-1]][c[0][i]];
56         for(int j=1;j<=ma;j++){
57             f[i][j][0]=min(f[i-1][j][0]+dis[c[0][i-1]][c[0][i]],f[i-1][j][1]+dis[c[1][i-1]][c[0][i]]*ke[i-1]+dis[c[0][i-1]][c[0][i]]*(1.0-ke[i-1]));
58             f[i][j][1]=min(f[i-1][j-1][0]+dis[c[0][i-1]][c[1][i]]*ke[i]+dis[c[0][i-1]][c[0][i]]*(1-ke[i]),
59             f[i-1][j-1][1]+dis[c[1][i-1]][c[1][i]]*ke[i]*ke[i-1]+dis[c[1][i-1]][c[0][i]]*ke[i-1]*(1.0-ke[i])
60             +dis[c[0][i-1]][c[1][i]]*(1.0-ke[i-1])*ke[i]+dis[c[0][i-1]][c[0][i]]*(1.0-ke[i])*(1.0-ke[i-1]));
61         }
62     }
63     for(int i=0;i<=k;i++){
64         ans=min(ans,min(f[t][i][0],f[t][i][1]));
65     }
66     printf("%.2f",ans);
67     return 0;
68 }
View Code

 

posted @ 2017-11-09 16:03  鲸头鹳  阅读(139)  评论(0编辑  收藏  举报