首页 > 代码库 > 洛谷P1850 换教室 最短路 + 动态规划

洛谷P1850 换教室 最短路 + 动态规划

洛谷P1850 换教室
最短路 + 动态规划
题解 首先预处理出任意两点的最短路
然后 dp
f[ i ][ j ][ 0/1 ] 现在是 第 i 个时间段,已经申请 过 j次了,该次是否成功 0 否 1 成功 的最小的期望
主要是四个方面的转移 前一个是否申请 成功 or失败 当前是否申请 成功or失败  

 

 1 #include <bits/stdc++.h> 
 2 #define For(i,j,k) for(int i=j;i<=k;i++)
 3 using namespace std ; 
 4 
 5 const int N = 2011,V = 311,inf = 1e9 ; 
 6 int a[N],b[N] ; 
 7 double d[V][V],c[N] ; 
 8 double f[N][N][2] ;
 9 int n,m,v,e ;    
10 
11 inline void init()  // 初始化 
12 {
13     For(i,0,V-1) 
14         For(j,0,V-1) 
15           if(i==j) 
16               d[ i ][ j ] = 0 ;
17           else 
18             d[ i ][ j ] = inf ; 
19             
20     For(i,0,N-1) 
21         For(j,0,N-1) 
22             f[ i ][ j ][ 0 ] = f[ i ][ j ][ 1 ] = inf ; 
23     f[ 1 ][ 0 ][ 0 ] = 0 ;    //第一个点要么从  a 出发 要么从  b出发 
24     f[ 1 ][ 1 ][ 1 ] = 0 ;    
25 }
26 
27 inline void floyd() 
28 {
29     For(k,1,v) 
30       For(i,1,v) 
31           For(j,1,v) 
32            d[ i ][ j ] = min(d[ i ][ j ],d[ i ][ k ]+d[ k ][ j ]) ;        //
33 }
34 
35 int main() 
36 {
37     scanf("%d%d%d%d",&n,&m,&v,&e) ; 
38     For(i,1,n) scanf("%d",&a[ i ]) ; 
39     For(i,1,n) scanf("%d",&b[ i ]) ; 
40     For(i,1,n) scanf("%lf",&c[ i ]) ; 
41     init() ; 
42     
43     For(i,1,e) 
44     {
45         int x,y,z ; 
46         scanf("%d%d%d",&x,&y,&z) ; 
47         if(x==y) continue ; 
48         if(z < d[x][y]) d[x][y] = z ; 
49         d[y][x] = d[x][y] ; 
50     }
51     floyd() ; 
52     For(i,2,n) 
53     {
54         f[ i ][ 0 ][ 0 ] = f[ i-1 ][ 0 ][ 0 ] + d[a[ i-1 ]][a[ i ]] ; 
55         For(j,1,min(m,i)) 
56         {
57             f[i][j][0] = min(f[i-1][j][0] + d[a[i-1]][a[i]],f[i-1][j][1] + d[a[i-1]][a[i]] * (1.0-c[ i-1 ]) + d[b[i-1]][a[i]] * c[ i-1 ]) ;
58             f[i][j][1] = f[i-1][j-1][0] + d[a[i-1]][a[i]] * (1.0-c[i]) + d[a[i-1]][b[ i ]] * c[ i ] ; 
59             double t = f[i-1][j-1][1] +d[a[i-1]][a[i]] * (1.0-c[i-1]) * (1.0-c[i]) ; 
60             t += d[b[i-1]][a[i]] * c[ i-1 ] * (1.0-c[ i ]) ; 
61             t += d[a[i-1]][b[i]] * (1.0-c[i-1]) * c[ i ] ; 
62             t += d[b[i-1]][b[i]] * c[i-1] * c[i] ; 
63             f[i][j][1] = min(f[i][j][1],t) ; 
64         } 
65     }
66     double ans = f[n][0][0] ; 
67     For(i,1,m) 
68         ans = min( ans,min( f[n][i][0],f[n][i][1] ) ) ; 
69     printf("%.2lf\n",ans) ;   
70     return 0 ; 
71 }

 

洛谷P1850 换教室 最短路 + 动态规划