1. 程式人生 > >洛谷P1850 換教室 最短路 + 動態規劃

洛谷P1850 換教室 最短路 + 動態規劃

nbsp span ini pan fine its 是否 log 動態

洛谷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 換教室 最短路 + 動態規劃