1. 程式人生 > >noip2016換教室(期望dp)

noip2016換教室(期望dp)

整體思路:

這節課換了教室的期望路程 = min(上節課換了教室的期望路程 + 上節課教室到這節課教室的期望路程, 上節課沒換教室的期望路程+ 上節課教室到這節課教室的期望路程)

這節課沒換教室的期望路程 = min(上節課換了教室的期望路程  + 上節課教室到這節課教室的期望路程,上節課沒換教室的期望路程+ 上節課教室到這節課教室的期望路程)

 上節課教室到這節課教室的期望路程 = 某一情況路程 * 這一情況發生的概率;

dp[i][j][0/1]第i節課換了j次這節課換或不換

細節:
初值,邊界,

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n, m, v, e,c[2005],d[2005],bian[2005][2005];
double k[2005],f[2005][2005][2],ans = 1e18;
int main()
{
    cin >> n >> m >> v >> e;
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &c[i]);
    }
    for(int i = 1; i <= n; i++)
    {
         scanf("%d", &d[i]);	
    }
    for(int i = 1; i <= n; i++)
    {
        scanf("%lf", &k[i]);
    }
    memset(bian,0x3f3f3f3f3f,sizeof(bian));
    for(int i = 1; i <= e; i++)
    {
        int x, y, w;
        scanf("%d%d%d", &x, &y, &w);
        bian[x][y] = min(w, bian[x][y]);
        bian[y][x] = bian[x][y];
    }
    for(int i = 1; i <= v; i++)
    bian[i][i] = 0;
     for(int e = 1; e <= v; e++) 
     for(int i = 1; i <= v; i++)
     for(int j = 1; j <= v; j++)
      bian[i][j] = min(bian[i][j],bian[i][e] + bian[e][j]); 
     for(int i = 1; i <= n; i++)
     for(int j =  0; j <= m; j++)
     {
     	f[i][j][0] = f[i][j][1] = 1e30;
     } 
     f[1][0][0] = f[1][1][1] = 0;
    for(int i = 2; i <= n; i++)
    {
    	int ha = min(i , m);
    	 for(int j = 0; j <= ha; j++)
        {
        f[i][j][0] = min(f[i][j][0], f[i-1][j][0] + bian[c[i-1]][c[i]]); 
     	f[i][j][0] = min(f[i][j][0],  f[i-1][j][1] + bian[d[i-1]][c[i]] *k[i - 1] + bian[c[i-1]][c[i]] * (1.0 - k[i - 1]));
          if(j >= 1)	
	     {
	   	 f[i][j][1] = min(f[i-1][j-1][0] + bian[c[i-1]][d[i]] * k[i] + bian[c[i -1]][c[i]] * (1.0 - k[i]),f[i][j][1]); 
         f[i][j][1] = min(f[i][j][1],f[i-1][j-1][1] + bian[d[i-1]][d[i]] * k[i]  * k[i-1] + bian[d[i-1]][c[i]] * k[i - 1] * (1.0 - k[i]) + bian[c[i-1]][d[i]] *(1.0 - k[i-1])*k[i] + bian[c[i-1]][c[i]] * (1.0 - k[i]) *(1.0 - k[i-1]));
	      }
        }
    }
    
     for(int i = 0; i <= m; i++)
     {
      double t = min(f[n][i][0] , f[n][i][1]);	
      ans = min(ans, t);
	 }
    
     printf("%0.2lf", ans);
     return 0;
}