[NOIp2016提高组]换教室
2017-11-04 13:53
267 查看
题目大意:
有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]));
#include<cstdio> #include<cctype> #include<algorithm> inline int getint() { register char ch; while(!isdigit(ch=getchar())); register int x=ch^'0'; while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); return x; } const int inf=0x7fffffff; const int N=2000,M=2001,V=301; int c ,d ,dis[V][V]; double k ,f[2][M][2]; int main() { int n=getint(),m=getint(),v=getint(),e=getint(); for(register int i=0;i<n;i++) c[i]=getint(); for(register int i=0;i<n;i++) d[i]=getint(); for(register int i=0;i<n;i++) scanf("%lf",&k[i]); for(register int i=1;i<=v;i++) { for(register int j=1;j<=v;j++) { if(i!=j) dis[i][j]=inf; } } for(register int i=0;i<e;i++) { const int u=getint(),v=getint(),w=getint(); dis[u][v]=dis[v][u]=std::min(dis[u][v],w); } for(register int k=1;k<=v;k++) { for(register int i=1;i<=v;i++) { if(dis[i][k]==inf) continue; for(register int j=1;j<=v;j++) { if(dis[k][j]==inf) continue; dis[i][j]=std::min(dis[i][j],dis[i][k]+dis[k][j]); } } } for(register int j=0;j<=m;j++) { f[0][j][0]=f[0][j][1]=1e9; } f[0][0][0]=f[0][1][1]=0; for(register int i=1;i<n;i++) { for(register int j=0;j<=m;j++) { f[i&1][j][0]=f[i&1][j][1]=1e9; } 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]); for(register int j=1;j<=m;j++) { 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]); 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])); } } double ans=1e9; for(register int i=0;i<=m;i++) { ans=std::min(ans,std::min(f[!(n&1)][i][0],f[!(n&1)][i][1])); } printf("%.2f\n",ans); return 0; }
相关文章推荐
- Luogu P1850 [NOIp提高组2016]换教室
- Noip 提高组 2016 Day1 T3 换教室 Floyd+期望dp
- 【NOIP2016提高组day1】换教室
- noip2016提高组 换教室 (数学期望+Floyd)
- 【NOIP 2016 提高组】换教室
- 【NOIP2016提高组T3】换教室-Floyd+概率DP
- 【NOIP2016提高组】换教室
- 【jzoj4905】【NOIP2016提高组】【换教室】【动态规划】【期望】
- NOIP2016提高组day1 换教室
- 【NOIP2016提高组复赛】换教室
- 【NOIP2016提高A组模拟9.7】千帆渡
- 【BZOJ4720】【NOIP2016】换教室
- 【jzoj4907】【NOIP2016提高组】【蚯蚓】【单调队列】
- NOIP2016提高组复赛解题报告
- 【NOIP2016提高组复赛官】组合数问题
- 【NOIP 2016 提高组】组合数问题
- 【NOIP 2016 提高组】蚯蚓
- 【JZOJ4771】【NOIP2016提高A组模拟9.9】爬山
- 【NOIP2016提高A组模拟9.9】爬山
- NOIP2016提高组Day1 真题测试