洛谷 P1850 换教室(期望dp)

传送门


解题思路

用dp[i][j][0/1]表示到第i节课、申请了j次,第i节课是否申请的最小体力和。

然后分别从dp[i-1][j][0]、dp[i-1][j][1],dp[i-1][j-1][0]、dp[i-1][j-1][1]疯狂转移过来。

先跑一边Floyd求最短路。

注意double无法用memset初始化。

具体看代码吧。

比较易懂。

AC代码

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cmath>
 4 #include<cstdio>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<queue>
 8 #include<set>
 9 #include<map>
10 #include<vector>
11 #include<iomanip>
12 #include<ctime>
13 #include<stack>
14 using namespace std;
15 int dis[305][305],n,m,v,e,c[2005],d[2005];
16 double dp[2005][2005][2],k[2005],ans=1000000;
17 int main()
18 {
19     cin>>n>>m>>v>>e;
20     for(int i=1;i<=v;i++){
21         for(int j=1;j<=v;j++){
22             dis[i][j]=1000000;
23         }
24     }
25     for(int i=1;i<=v;i++) dis[i][i]=0;
26     for(int i=1;i<=n;i++) cin>>c[i]; 
27     for(int i=1;i<=n;i++) cin>>d[i]; 
28     for(int i=1;i<=n;i++) cin>>k[i]; 
29     for(int i=1;i<=e;i++){
30         int u,v,value;
31         cin>>u>>v>>value;
32         dis[u][v]=min(dis[u][v],value);
33         dis[v][u]=min(dis[v][u],value);
34     }
35     for(int kk=1;kk<=v;kk++){
36         for(int i=1;i<=v;i++){
37             for(int j=1;j<=v;j++){
38                 dis[i][j]=min(dis[i][j],dis[i][kk]+dis[kk][j]);
39             }
40         }
41     }
42     for(int i=1;i<=n;i++){
43         for(int j=0;j<=m;j++){
44             dp[i][j][0]=dp[i][j][1]=1000000;
45         }
46     }
47     dp[1][0][0]=dp[1][1][1]=0;
48     for(int i=2;i<=n;i++){
49         dp[i][0][0]=dp[i-1][0][0]+dis[c[i]][c[i-1]];
50         for(int j=1;j<=min(i,m);j++){
51             dp[i][j][0]=min(dp[i-1][j][0]+dis[c[i]][c[i-1]],dp[i-1][j][1]+k[i-1]*dis[c[i]][d[i-1]]+(1-k[i-1])*dis[c[i]][c[i-1]]);
52             dp[i][j][1]=min(dp[i-1][j-1][0]+dis[c[i]][c[i-1]]*(1-k[i])+dis[d[i]][c[i-1]]*k[i],dp[i-1][j-1][1]+dis[c[i]][c[i-1]]*(1-k[i])*(1-k[i-1])+dis[c[i]][d[i-1]]*(1-k[i])*k[i-1]+dis[d[i]][c[i-1]]*k[i]*(1-k[i-1])+dis[d[i]][d[i-1]]*k[i]*k[i-1]);
53         }
54     }
55     for(int i=0;i<=min(n,m);i++){
56         ans=min(ans,min(dp[n][i][0],dp[n][i][1]));
57     }
58     printf("%.2lf",ans);   
59     return 0;
60 }

//NOIP2016提高组 Day1 t3

posted @ 2020-11-24 00:22  尹昱钦  阅读(102)  评论(0编辑  收藏  举报