zoukankan      html  css  js  c++  java
  • AcWing233 换教室(数学)

    这道题有意思的地方是,他要求提前决策,不能实时决策,这个意思是,我们不能记录当前点是否成功的状态,而只能记录是否申请的状态。

    这道题比较明显的状态是f[][][],前i个,申请了j次,第i个有无申请。

    但是我想通过记忆化搜索来做,因此将这个状态设计为前i-1个,申请了j次,第i-1个有无申请。这样初始状态就只有一种1,0,0,表示0的位置,申请0次,第0个没申请

    因为我们根本没有第0个,所以只有他是合法的。

    问的是最短路,只要floyd跑一下就行

    在记忆化的时候,有很多情况

    当i-1个没申请,那么我们i个可以申请或不申请

    当i-1个申请了,同理。

    当两个都申请了的话,就有4种情况,都没申请就是1种,其他都是两种

    注意当已经申请等于m次,就不能再申请,因此要特判,细节比较多。一般floyd就用邻接矩阵存,注意初始化

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #include<map>
    #include<string>
    #include<vector>
    using namespace std;
    const int N=2010;
    int n,m,v,e;
    int g[N][N];
    int pos[N][2];
    double p[N];
    double f[N][N][2];
    void floyd(){
        int k,i,j;
        for(i=1;i<=v;i++)
        g[i][i]=0;
        for(k=1;k<=v;k++){
            for(i=1;i<=v;i++){
                for(j=1;j<=v;j++)
                g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
            }
        }
        for(int j=0;j<=v;j++) g[0][j] = 0;
    }
    double dfs(int i,int j,int flag){
        if(i==n+1)
        return 0;
        auto &x=f[i][j][flag];
        if(x!=-1)
        return x;
        double ans1=0;
        double ans0=0;
        if(flag==0) ans0 = dfs(i+1, j, 0) + g[pos[i-1][0]][pos[i][0]];
        else ans0 = dfs(i+1, j, 0) + p[i-1]*g[pos[i-1][1]][pos[i][0]] + (1-p[i-1])*g[pos[i-1][0]][pos[i][0]];
        if(j==m) return x= ans0;
        if(!flag){
            ans1=p[i]*(dfs(i+1,j+1,1)+g[pos[i-1][0]][pos[i][1]])+(1-p[i])*(dfs(i+1,j+1,1)+g[pos[i-1][0]][pos[i][0]]);
        }
        else{
            ans1=p[i]*(dfs(i+1,j+1,1)+p[i-1]*(g[pos[i-1][1]][pos[i][1]])+(1-p[i-1])*(g[pos[i-1][0]][pos[i][1]]))+
                 (1-p[i])*(dfs(i+1,j+1,1)+p[i-1]*(g[pos[i-1][1]][pos[i][0]])+(1-p[i-1])*(g[pos[i-1][0]][pos[i][0]]));
        }
        return x=min(ans1,ans0);
    }
    int main(){
        cin>>n>>m>>v>>e;
        int i;
        for(i=1;i<=n;i++)
            cin>>pos[i][0];
        for(i=1;i<=n;i++)
            cin>>pos[i][1];
        for(i=1;i<=n;i++)
            cin>>p[i];
        memset(g,1,sizeof g);
        for(i=1;i<=e;i++){
            int a,b,w;
            cin>>a>>b>>w;
            g[a][b]=g[b][a]=min(w,g[a][b]);
        }
        floyd();
        for(i=1;i<=n;i++){
            for(int j=0;j<=m;j++){
                f[i][j][0]=f[i][j][1]=-1;
            }
        }
        double ans=dfs(1,0,0);
        printf("%.2f
    ",ans);
        return 0;
    }
    View Code
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    Python中的try...except...finally
    JavaScript 实现双向队列并用此来测试一个单词是否为回文
    js 触发 change 事件
    MySQL8 重置改root密码及开放远程访问
    根据数组下标在MongoDB中修改数组元素
    pymongo CursorNotFound错误
    mongodb根据子项中的指标查找最小或最大值
    正则文本过滤时的一些注意事项
    github page更新后不生效
    Xpath同时选取不同属性的元素
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12713708.html
Copyright © 2011-2022 走看看