【一天一DP计划】概率期望DP

##换教室

floyd三看:

  • dis[u][v]=dis[v][u]=min(dis[u][v],w)
  • mem了dis后,rep(i,1,点的个数)dis[i][i]=0
/*
debug:
	注意读题啊……是双向通行的
reference:
	ccf提高篇P279
Date:
	2019.10.07
sol:
	
*/
const int N=2e3+10;
int n,m,v,e;
int c[N],d[N];
double k[N],f[N][N][2];
int dis[310][310];

int main(){
	#ifdef WIN32
	freopen("huanjiaoshi.txt","r",stdin);
	#endif
	rd(n),rd(m),rd(v),rd(e);
	rep(i,1,n)rd(c[i]);rep(i,1,n)rd(d[i]);rep(i,1,n)scanf("%lf",&k[i]);
	mem(dis,0x3f);
	rep(i,1,v)dis[i][i]=0;
	rep(i,1,e){
		int u,v,w;rd(u),rd(v),rd(w);
		dis[u][v]=dis[v][u]=min(dis[u][v],w);///////////////////////无向边!!! 
	}
	rep(kk,1,v)
		rep(i,1,v)
			rep(j,1,v)
				dis[i][j]=min(dis[i][j],dis[i][kk]+dis[kk][j]); 
	rep(i,1,n)
		rep(j,0,m)
			f[i][j][0]=f[i][j][1]=1.0*1e9;
	f[1][0][0]=f[1][1][1]=0;
	rep(i,2,n){
		rep(j,0,min(i,m)){
			//第i节课不申请 
			f[i][j][0]=min(f[i][j][0],
				f[i-1][j][1]+k[i-1]*dis[d[i-1]][c[i]]+(1.0-k[i-1])*dis[c[i-1]][c[i]]);
			f[i][j][0]=min(f[i][j][0],
				f[i-1][j][0]+dis[c[i-1]][c[i]]);
			//第i节课要申请
			if(j>0){//得保证有上一堂课 
				f[i][j][1]=min(f[i][j][1],
					f[i-1][j-1][0]+k[i]*dis[c[i-1]][d[i]]+(1.0-k[i])*dis[c[i-1]][c[i]]);
				f[i][j][1]=min(f[i][j][1],
					f[i-1][j-1][1]+
					k[i-1]*k[i]*dis[d[i-1]][d[i]]+
					k[i-1]*(1.0-k[i])*dis[d[i-1]][c[i]]+
					(1.0-k[i-1])*k[i]*dis[c[i-1]][d[i]]+
					(1.0-k[i-1])*(1.0-k[i])*dis[c[i-1]][c[i]]);
			}
		}
	}
	double ans=1e9*1.0;
	rep(i,0,m)
		ans=min(ans,min(f[n][i][0],f[n][i][1]));
	printf("%.2lf",ans);
	return 0;
}
原文地址:https://www.cnblogs.com/sjsjsj-minus-Si/p/11634646.html