[NOIp2016提高组]换教室
题目大意:
有n节课,第i节课在c[i]上课,同时d[i]也有一节课d[i]。
你有权利向教务处发出m次申请把自己的教室改到d[i],相应的批准概率是k[i]。
教室是图上的一些点,其中每条边都有边权。
问你上完所有课走的总路程的期望。
思路:
动态规划。
f[i][j][0/1]表示上了i个课,换了j次教室,这门课有没有换教室。
转移方程为:
f[i][j][0]=min(f[i-1][j][0]+dis[c[i-1]][c[i]],f[i-1][j][1]+dis[c[i-1]][c[i]]*(1-k[i-1])+dis[d[i-1]][c[i]]*k[i-1]);
f[i][j][1]=min(f[i-1][j-1][0]+dis[c[i-1]][d[i]]*k[i]+dis[c[i-1]][c[i]]*(1-k[i]),f[i-1][j-1][1]+dis[d[i-1]][d[i]]*k[i-1]*k[i]+dis[d[i-1]][c[i]]*k[i-1]*(1-k[i])+dis[c[i-1]][d[i]]*(1-k[i-1])*k[i]+dis[c[i-1]][c[i]]*(1-k[i-1])*(1-k[i]));
1 #include<cstdio> 2 #include<cctype> 3 #include<algorithm> 4 inline int getint() { 5 register char ch; 6 while(!isdigit(ch=getchar())); 7 register int x=ch^'0'; 8 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 9 return x; 10 } 11 const int inf=0x7fffffff; 12 const int N=2000,M=2001,V=301; 13 int c[N],d[N],dis[V][V]; 14 double k[N],f[2][M][2]; 15 int main() { 16 int n=getint(),m=getint(),v=getint(),e=getint(); 17 for(register int i=0;i<n;i++) c[i]=getint(); 18 for(register int i=0;i<n;i++) d[i]=getint(); 19 for(register int i=0;i<n;i++) scanf("%lf",&k[i]); 20 for(register int i=1;i<=v;i++) { 21 for(register int j=1;j<=v;j++) { 22 if(i!=j) dis[i][j]=inf; 23 } 24 } 25 for(register int i=0;i<e;i++) { 26 const int u=getint(),v=getint(),w=getint(); 27 dis[u][v]=dis[v][u]=std::min(dis[u][v],w); 28 } 29 for(register int k=1;k<=v;k++) { 30 for(register int i=1;i<=v;i++) { 31 if(dis[i][k]==inf) continue; 32 for(register int j=1;j<=v;j++) { 33 if(dis[k][j]==inf) continue; 34 dis[i][j]=std::min(dis[i][j],dis[i][k]+dis[k][j]); 35 } 36 } 37 } 38 for(register int j=0;j<=m;j++) { 39 f[0][j][0]=f[0][j][1]=1e9; 40 } 41 f[0][0][0]=f[0][1][1]=0; 42 for(register int i=1;i<n;i++) { 43 for(register int j=0;j<=m;j++) { 44 f[i&1][j][0]=f[i&1][j][1]=1e9; 45 } 46 f[i&1][0][0]=std::min(f[!(i&1)][0][0]+dis[c[i-1]][c[i]],f[!(i&1)][0][1]+dis[c[i-1]][c[i]]*(1-k[i-1])+dis[d[i-1]][c[i]]*k[i-1]); 47 for(register int j=1;j<=m;j++) { 48 f[i&1][j][0]=std::min(f[!(i&1)][j][0]+dis[c[i-1]][c[i]],f[!(i&1)][j][1]+dis[c[i-1]][c[i]]*(1-k[i-1])+dis[d[i-1]][c[i]]*k[i-1]); 49 f[i&1][j][1]=std::min(f[!(i&1)][j-1][0]+dis[c[i-1]][d[i]]*k[i]+dis[c[i-1]][c[i]]*(1-k[i]),f[!(i&1)][j-1][1]+dis[d[i-1]][d[i]]*k[i-1]*k[i]+dis[d[i-1]][c[i]]*k[i-1]*(1-k[i])+dis[c[i-1]][d[i]]*(1-k[i-1])*k[i]+dis[c[i-1]][c[i]]*(1-k[i-1])*(1-k[i])); 50 } 51 } 52 double ans=1e9; 53 for(register int i=0;i<=m;i++) { 54 ans=std::min(ans,std::min(f[!(n&1)][i][0],f[!(n&1)][i][1])); 55 } 56 printf("%.2f\n",ans); 57 return 0; 58 }