JZYZOJ1457 [NOIP2016]换教室 期望dp 动态规划 floyd算法 最短路

时间:2023-03-10 03:41:20
JZYZOJ1457 [NOIP2016]换教室 期望dp 动态规划 floyd算法 最短路

http://172.20.6.3/Problem_Show.asp?id=1457

我不知道为什么我倒着推期望只有80分,所以我妥协了,我对着题解写了个正的,我有罪。

 #include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<queue>
using namespace std;
const int maxn=;
int t,k,n,m;
int c[][maxn]={};
int dis[][]={};
int vis[maxn]={};
double f[maxn][maxn][];
double ke[maxn]={};
int main(){
//freopen("wtf.in","r",stdin);
scanf("%d%d%d%d",&t,&k,&n,&m);
int x,y,v;
for(int i=;i<=t;i++){
scanf("%d",&c[][i]);
}
for(int i=;i<=t;i++){
scanf("%d",&c[][i]);
}
for(int i=;i<=t;i++){
scanf("%lf",&ke[i]);
}
memset(dis,,sizeof(dis));
for(int i=;i<=n;i++) dis[i][i]=;
for(int i=;i<=m;i++){
scanf("%d%d%d",&x,&y,&v);
dis[x][y]=min(dis[x][y],v);
dis[y][x]=dis[x][y];
}
for(int i=;i<=n;i++){
for(int j=;j<=n;j++){
if(i==j)continue;
for(int w=;w<=n;w++){
if(dis[j][i]+dis[i][w]<dis[j][w]){
dis[j][w]=dis[j][i]+dis[i][w];
}
}
}
}
for(int i=;i<=n;i++) dis[i][]=dis[][i]=;
for(int i=;i<=t;i++){
for(int j=;j<=k;j++){
f[i][j][]=20000000000.0;
f[i][j][]=20000000000.0;
}
}double ans=f[][][];
f[][][]=f[][][]=;
for(int i=;i<=t;i++){
int ma=min(i,k);
f[i][][]=f[i-][][]+dis[c[][i-]][c[][i]];
for(int j=;j<=ma;j++){
f[i][j][]=min(f[i-][j][]+dis[c[][i-]][c[][i]],f[i-][j][]+dis[c[][i-]][c[][i]]*ke[i-]+dis[c[][i-]][c[][i]]*(1.0-ke[i-]));
f[i][j][]=min(f[i-][j-][]+dis[c[][i-]][c[][i]]*ke[i]+dis[c[][i-]][c[][i]]*(-ke[i]),
f[i-][j-][]+dis[c[][i-]][c[][i]]*ke[i]*ke[i-]+dis[c[][i-]][c[][i]]*ke[i-]*(1.0-ke[i])
+dis[c[][i-]][c[][i]]*(1.0-ke[i-])*ke[i]+dis[c[][i-]][c[][i]]*(1.0-ke[i])*(1.0-ke[i-]));
}
}
for(int i=;i<=k;i++){
ans=min(ans,min(f[t][i][],f[t][i][]));
}
printf("%.2f",ans);
return ;
}