• 概率DP 换教室


    传送门:http://cogs.pro/cogs/problem/problem.php?pid=2558

           教室数很小,路又很多,考虑用floyd.(开始把k打里面了,颜面扫地。。)

           因为只能提交m个,所以数组就是三维,f[i][j][0/1].i表示第几节课,j表示到i时选了多少节,第三维表示i是否选

           既然提交后不知道能否通过,所以期望要分类讨论(废话)一共四种情况,也就是i选没选,i-1选没选,

           r1(原来的),r2(换后的)。

           分别写一下吧,

           i-1不选,i不选,f[i][j][0]=f[i-1][j][0]+dis[r1[i-1]][r1[i]];

           i-1选,i不选,      f[i][j][0]=f[i-1][j][1]+luck[i-1]*dis[r2[i-1]][r1[i]];

           i-1不选,i 选 ,     类似。

           i-1,i均选          讨论四种,两个概率相乘。

          打的时候,觉得从零开始很别扭,就初始化出了1的

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #define N 2000
    using namespace std;
    int n,m,v,e,r1[N+5],r2[N+5],dis[305][305];
    int fa[N+5];
    double luck[N+5],f[N+5][N+5][2],unluck[N+5];
    void init()
    {
    	memset(dis,0x3f,sizeof(dis));
    	scanf("%d%d%d%d",&n,&m,&v,&e);
    	for(int i=1;i<=n;i++)
    	   for(int j=0;j<=m;j++)
    	       f[i][j][0]=f[i][j][1]=1e18;
    	for(int i=1;i<=n;i++)
    	   scanf("%d",&r1[i]);
    	for(int i=1;i<=n;i++)
    	   scanf("%d",&r2[i]);
    	for(int i=1;i<=n;i++)
    	   scanf("%lf",&luck[i]),unluck[i]=1-luck[i];
    	int x,y,z;
    	for(int i=1;i<=e;i++)
    	{
    		scanf("%d%d%d",&x,&y,&z);
    	    dis[x][y]=min(dis[x][y],z);
    	    dis[y][x]=dis[x][y];
    	}   
    }
    int yjn()
    {
    	//freopen("classrooma.in","r",stdin);
    	//freopen("classrooma.out","w",stdout);
    	init();
    	for(int i=1;i<=v;i++)dis[i][i]=0;
    	for(int k=1;k<=v;k++)
    	   for(int i=1;i<=v;i++)
    	     if(i!=k)
    	        for(int j=1;j<=v;j++)
    	         if(j!=i&&k!=j)
    			     dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
    	
    	f[1][0][0]=f[1][1][1]=0.0;
    	for(int i=1;i<n;i++)
    	   for(int j=0;j<=m;j++)
    	   {
    	   	    f[i+1][j][0]=min(f[i+1][j][0],f[i][j][0]+dis[r1[i]][r1[i+1]]);
    	   	    f[i+1][j][0]=min(f[i+1][j][0],f[i][j][1]+luck[i]*dis[r2[i]][r1[i+1]]+unluck[i]*dis[r1[i]][r1[i+1]]);
    	   	    if(j<m)
    	   		{
    				f[i+1][j+1][1]=min(f[i+1][j+1][1],f[i][j][0]+luck[i+1]*dis[r1[i]][r2[i+1]]+unluck[i+1]*dis[r1[i]][r1[i+1]]);
    	   	        f[i+1][j+1][1]=min(f[i+1][j+1][1],f[i][j][1]+luck[i]*unluck[i+1]*dis[r2[i]][r1[i+1]]+unluck[i]*unluck[i+1]*dis[r1[i]][r1[i+1]]+unluck[i]*luck[i+1]*dis[r1[i]][r2[i+1]]+luck[i]*luck[i+1]*dis[r2[i]][r2[i+1]]);
    	  		}
    	   }
    	double s=1e18;
    	for(int i=0;i<=m;i++)
    	   s=min(s,min(f[n][i][0],f[n][i][1]));
    	printf("%0.2lf",s);
    }
    int qty=yjn();
    int main(){;}


    
    

    
    
    
       
    
  • 相关阅读:
    IE、FF、Chrome浏览器中的JS差异介绍
    防止 jsp被sql注入的五种方法
    读取Excel数据到Table表中
    C#获取IP地址
    JavaScript之web通信
    Unity使用 转载
    EF5 通用数据层 增删改查操作,泛型类
    Entity FrameWork 5 增删改查 & 直接调用sql语句
    asp.net重启web应用程序域
    .net创建activex实现摄像头拍照
  • 原文地址:https://www.cnblogs.com/QTY2001/p/7632779.html
Copyright © 2020-2023  润新知