首页 > 其他 > 详细

洛谷 1850 NOIP2016提高组 换教室

时间:2018-10-18 10:18:47      阅读:177      评论:0      收藏:0      [点我收藏+]

技术分享图片

技术分享图片

【题解】

  先用floyed处理出两点间的最短路。

  设f[i][j][k]表示走到第i个教室,总共换了j次,当前换或者不换,期望的最小移动距离。

  分情况讨论来转移即可。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define LL long long
 5 #define rg register
 6 #define N 2010
 7 using namespace std;
 8 int n,m,v,e,dis[310][310],c[N],d[N];
 9 double f[N][N][2],k[N],ans=2e9;
10 inline int read(){
11     int k=0,f=1; char c=getchar();
12     while(c<0||c>9)c==-&&(f=-1),c=getchar();
13     while(0<=c&&c<=9)k=k*10+c-0,c=getchar();
14     return k*f;
15 } 
16 int main(){
17     n=read(); m=read(); v=read(); e=read();
18     for(rg int i=0;i<=n;i++)
19         for(rg int j=0;j<=m;j++) f[i][j][0]=f[i][j][1]=1e9;
20     f[1][0][0]=f[1][1][1]=0;
21     for(rg int i=1;i<=v;i++)
22         for(rg int j=1;j<=v;j++) if(i!=j)dis[i][j]=1e9;
23     for(rg int i=1;i<=n;i++) c[i]=read();
24     for(rg int i=1;i<=n;i++) d[i]=read();
25     for(rg int i=1;i<=n;i++) scanf("%lf",&k[i]);
26     for(rg int i=1;i<=e;i++){
27         int u=read(),v=read();
28         dis[u][v]=dis[v][u]=min(dis[u][v],read());
29     }
30     for(rg int mid=1;mid<=v;mid++)
31         for(rg int i=1;i<=v;i++)
32             for(rg int j=1;j<=v;j++) dis[i][j]=dis[j][i]=min(dis[i][j],dis[i][mid]+dis[mid][j]);
33     for(rg int i=2;i<=n;i++){
34         int num=min(i,m);
35         for(rg int j=0;j<=num;j++){
36             f[i][j][0]=min(f[i][j][0],f[i-1][j][0]+dis[c[i-1]][c[i]]);
37             if(j>=1) 
38                 f[i][j][0]=min(f[i][j][0],f[i-1][j][1]+k[i-1]*dis[d[i-1]][c[i]]+(1-k[i-1])*dis[c[i-1]][c[i]]);
39             if(j>=1)
40                 f[i][j][1]=min(f[i][j][1],f[i-1][j-1][0]+k[i]*dis[c[i-1]][d[i]]+(1-k[i])*dis[c[i-1]][c[i]]);
41             if(j>=2){
42                 double tmp=0;
43                 tmp+=k[i-1]*k[i]*dis[d[i-1]][d[i]] + k[i-1]*(1-k[i])*dis[d[i-1]][c[i]];
44                 tmp+=(1-k[i-1])*k[i]*dis[c[i-1]][d[i]] + (1-k[i-1])*(1-k[i])*dis[c[i-1]][c[i]];
45                 f[i][j][1]=min(f[i][j][1],f[i-1][j-1][1]+tmp);
46             }
47         }
48     }
49     for(rg int i=0;i<=m;i++) ans=min(ans,min(f[n][i][0],f[n][i][1]));
50     printf("%.2lf\n",ans);
51     return 0;
52 }

 

洛谷 1850 NOIP2016提高组 换教室

原文:https://www.cnblogs.com/DriverLao/p/9808271.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!