• [洛谷P1850][题解]换教室


    题目戳此

    一个比较毒瘤的DP题。

    设f[i][j][1/0]为前i个时段、申请j次、第i个时段申请成功与否

    思考下面几种情况:

    一:i未申请f[i][j][0]

    (1)i-1申请

    1.i-1申请成功

    2.i-1申请失败

    (2)i-1未申请

    二:i申请f[i][j][1]

    (1)i-1申请

    1.前后均成功

    2.前成功后失败

    3.前失败后成功

    4.前后均失败

    (2)i-1未申请

    1.i申请成功

    2.i申请失败

    以上九种情况都体现在代码里了:

     1 #include<bits/stdc++.h>
     2 #define LL long long
     3 #define rg register
     4 #define us unsigned
     5 #define eps 1e-6
     6 #define INF 0x3f3f3f3f
     7 #define ls k<<1
     8 #define rs k<<1|1
     9 #define tmid ((tr[k].l+tr[k].r)>>1)
    10 #define nmid ((l+r)>>1)
    11 #define Thispoint tr[k].l==tr[k].r
    12 #define pushup tr[k].wei=tr[ls].wei+tr[rs].wei
    13 using namespace std;
    14 inline void Read(int &x){
    15     int f=1;
    16     char c=getchar();
    17     x=0;
    18     while(c<'0'||c>'9'){
    19         if(c=='-')f=-1;
    20         c=getchar();
    21     }
    22     while(c>='0'&&c<='9'){
    23         x=(x<<3)+(x<<1)+c-'0';
    24         c=getchar();
    25     }
    26     x*=f;
    27 }
    28 int n,m,v,e;
    29 int c[2010],d[2010],dis[310][310];
    30 double k[2010],f[2010][2010][2];
    31 inline void Initi(){
    32     Read(n),Read(m),Read(v),Read(e);
    33     for(int i=1;i<=v;i++){
    34         for(int j=1;j<i;j++){
    35             dis[i][j]=dis[j][i]=INF;
    36         }
    37     }
    38     for(int i=1;i<=n;i++)Read(c[i]);
    39     for(int i=1;i<=n;i++)Read(d[i]);
    40     for(int i=1;i<=n;i++)cin>>k[i];
    41     for(int i=1;i<=e;i++){
    42         int a,b,w;
    43         Read(a),Read(b),Read(w);
    44         dis[a][b]=min(dis[a][b],w);
    45         dis[b][a]=dis[a][b];
    46     }
    47 }
    48 inline void Floyd(){
    49     for(int k=1;k<=v;k++){
    50         for(int i=1;i<=v;i++){
    51             for(int j=1;j<i;j++){
    52                 if(dis[i][j]>dis[i][k]+dis[k][j]){
    53                     dis[i][j]=dis[j][i]=dis[i][k]+dis[k][j];
    54                 }
    55             }
    56         }
    57     }
    58 }
    59 inline void DP(){
    60     for(int i=1;i<=n;i++){
    61         for(int j=0;j<=m;j++){
    62             f[i][j][0]=f[i][j][1]=INF;
    63         }
    64     }
    65     f[1][0][0]=0;
    66     f[1][1][1]=0;
    67     for(int i=2;i<=n;i++){
    68         for(int j=0;j<=m;j++){
    69             f[i][j][0]=min(f[i-1][j][1]+k[i-1]*dis[d[i-1]][c[i]]+(1-k[i-1])*dis[c[i-1]][c[i]],f[i-1][j][0]+dis[c[i-1]][c[i]]);
    70             if(j!=0){
    71                 f[i][j][1]=min(f[i-1][j-1][1]+k[i-1]*k[i]*dis[d[i-1]][d[i]]+k[i-1]*(1-k[i])*dis[d[i-1]][c[i]]+(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]],f[i-1][j-1][0]+k[i]*dis[c[i-1]][d[i]]+(1-k[i])*dis[c[i-1]][c[i]]);
    72             }
    73         }
    74     }
    75 }
    76 inline void Print(){
    77     double ans=INF;
    78     for(int i=0;i<=m;i++){
    79 //        cout<<f[n][i][0]<<" "<<f[n][i][1]<<endl;
    80         ans=min(ans,min(f[n][i][0],f[n][i][1]));
    81     }
    82     printf("%.2lf
    ",ans);
    83 }
    84 int main(){
    85     Initi();
    86     Floyd();
    87     DP();
    88     Print();
    89     return 0;
    90 }

    完结撒花~~~

    内容来自_ajhfff_的博客(https://www.cnblogs.com/juruoajh/),未经允许,不得转载。
  • 相关阅读:
    C语言第五次作业
    c语言第4次作业
    第12次作业
    C语言第9次作业
    C语言第8次作业2
    C语言第8次作业
    C语言第七次作业---要死了----
    C语言第七次作业
    物联网工程实践第二次作业
    物联网工程实践第一次作业
  • 原文地址:https://www.cnblogs.com/juruoajh/p/12342735.html
Copyright © 2020-2023  润新知