zoukankan      html  css  js  c++  java
  • [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
    ",ans);
    57     return 0;
    58 }
  • 相关阅读:
    BNUOJ 12756 Social Holidaying(二分匹配)
    HDU 1114 Piggy-Bank(完全背包)
    HDU 2844 Coins (多重背包)
    HDU 2602 Bone Collector(01背包)
    HDU 1171 Big Event in HDU(01背包)
    HDU 2571 命运 (入门dp)
    HDU 1069 Monkey and Banana(最长递减子序列)
    HDU 1160 FatMouse's Speed (最长上升子序列)
    HDU 2594 KMP
    POJ 3783 Balls --扔鸡蛋问题 经典DP
  • 原文地址:https://www.cnblogs.com/skylee03/p/7783190.html
Copyright © 2011-2022 走看看