JZYZOJ1457 [NOIP2016]换教室 期望dp 动态规划 floyd算法 最短路
http://172.20.6.3/Problem_Show.asp?id=1457
我不知道为什么我倒着推期望只有80分,所以我妥协了,我对着题解写了个正的,我有罪。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #include<iostream> 6 #include<queue> 7 using namespace std; 8 const int maxn=2010; 9 int t,k,n,m; 10 int c[2][maxn]={}; 11 int dis[310][310]={}; 12 int vis[maxn]={}; 13 double f[maxn][maxn][2]; 14 double ke[maxn]={}; 15 int main(){ 16 //freopen("wtf.in","r",stdin); 17 scanf("%d%d%d%d",&t,&k,&n,&m); 18 int x,y,v; 19 for(int i=1;i<=t;i++){ 20 scanf("%d",&c[0][i]); 21 } 22 for(int i=1;i<=t;i++){ 23 scanf("%d",&c[1][i]); 24 } 25 for(int i=1;i<=t;i++){ 26 scanf("%lf",&ke[i]); 27 } 28 memset(dis,63,sizeof(dis)); 29 for(int i=1;i<=n;i++) dis[i][i]=0; 30 for(int i=1;i<=m;i++){ 31 scanf("%d%d%d",&x,&y,&v); 32 dis[x][y]=min(dis[x][y],v); 33 dis[y][x]=dis[x][y]; 34 } 35 for(int i=1;i<=n;i++){ 36 for(int j=1;j<=n;j++){ 37 if(i==j)continue; 38 for(int w=1;w<=n;w++){ 39 if(dis[j][i]+dis[i][w]<dis[j][w]){ 40 dis[j][w]=dis[j][i]+dis[i][w]; 41 } 42 } 43 } 44 } 45 for(int i=1;i<=n;i++) dis[i][0]=dis[0][i]=0; 46 for(int i=0;i<=t;i++){ 47 for(int j=0;j<=k;j++){ 48 f[i][j][1]=20000000000.0; 49 f[i][j][0]=20000000000.0; 50 } 51 }double ans=f[0][0][0]; 52 f[1][0][0]=f[1][1][1]=0; 53 for(int i=2;i<=t;i++){ 54 int ma=min(i,k); 55 f[i][0][0]=f[i-1][0][0]+dis[c[0][i-1]][c[0][i]]; 56 for(int j=1;j<=ma;j++){ 57 f[i][j][0]=min(f[i-1][j][0]+dis[c[0][i-1]][c[0][i]],f[i-1][j][1]+dis[c[1][i-1]][c[0][i]]*ke[i-1]+dis[c[0][i-1]][c[0][i]]*(1.0-ke[i-1])); 58 f[i][j][1]=min(f[i-1][j-1][0]+dis[c[0][i-1]][c[1][i]]*ke[i]+dis[c[0][i-1]][c[0][i]]*(1-ke[i]), 59 f[i-1][j-1][1]+dis[c[1][i-1]][c[1][i]]*ke[i]*ke[i-1]+dis[c[1][i-1]][c[0][i]]*ke[i-1]*(1.0-ke[i]) 60 +dis[c[0][i-1]][c[1][i]]*(1.0-ke[i-1])*ke[i]+dis[c[0][i-1]][c[0][i]]*(1.0-ke[i])*(1.0-ke[i-1])); 61 } 62 } 63 for(int i=0;i<=k;i++){ 64 ans=min(ans,min(f[t][i][0],f[t][i][1])); 65 } 66 printf("%.2f",ans); 67 return 0; 68 }