zoukankan      html  css  js  c++  java
  • NOIP 2016 D1T3 换教室

    为什么我觉得这年D1非常之丧……

    题目链接

    看到题目有点晕……,反正发现v<=500之后先写了floyd,不写白不写。

    现在我们有任意两点之间的最短路了,考虑dp(i表示考虑到第i个时间段)

    f[i][j][0]=min(跑到c[i]的期望距离)

    f[i][j][1]表示min(跑到c[i]的期望距离*(1-k[i])+跑到d[i]的期望距离*k[i] )(即假设在i交了申请跑到第i个教室的最短期望距离)

    什么意思呢?

    先设 g[x] = 跑到x的期望距离

    我们假设有 i 要从 i-1 转移。

    假若i-1处不交转课申请,无论对于d[i]还是c[i] 我们肯定希望 g[c[i-1]] 越小越好。

    假若i-1处交了转课申请,同理

    我们肯定希望 (g[c[i-1]]+dis[c[i-1]][c[i]])*(1-k[i-1])+(g[d[i-1]]+dis[d[i-1]][c[i]])*k[i-1] 以及

           (g[c[i-1]]+dis[c[i-1]][d[i]])*(1-k[i-1])+(g[d[i-1]]+dis[d[i-1]][d[i]])*k[i-1]越小越好。

    发现dis其实无法改变,考虑把dis删去,得到g[c[i-1]]*(1-k[i-1])+g[d[i-1]]*k[i-1],我们要最小化的是它。

    这时我们发现一个dp[i][j]其实需要维护两个状态才能满足最优子结构的性质。

    因此就有了上面的状态表示,我们考虑n^2转移即可,转移方程不难想,但是很难写……

    代码(式子巨长,细节巨多,心力交瘁):

    #include<cstdio>
    #include<cstring>
    #define min(a,b) (a<b?a:b)
    #define init(x,p) memset(x,p,sizeof(x))
    int map[505][505];
    int n,m,v,e,c[2005],d[2005];
    double k[2005],dp[2005][2005][4];
    void init_dp();
    void floyd();
    int main(){
    //    freopen("xx.txt","r",stdin);
        init(map,0x3f);
        scanf("%d%d%d%d",&n,&m,&v,&e);
        for(int i=1;i<=n;++i){
            scanf("%d",&c[i]);
            if(c[i]==0) return -1;
        }
        for(int i=1;i<=n;++i) scanf("%d",&d[i]);
        for(int i=1;i<=n;++i) scanf("%lf",&k[i]);
        for(int i=1;i<=e;++i){
            int a,b,cd;
            scanf("%d%d%d",&a,&b,&cd);
            map[a][b]=map[b][a]=min(map[b][a],cd);
        }
        for(int i=1;i<=v;++i) map[i][i]=0;
        floyd();
        init_dp();
        dp[1][0][0]=dp[1][0][1]=0;
        #define f map
        for(int i=2;i<=n;++i){
            for(int j=0;j<=min(n,m);++j){
                if(!j){
                    dp[i][j][0]=dp[i-1][j][0]+f[c[i-1]][c[i]];
                    dp[i][j][1]=f[c[i-1]][c[i]]*(1-k[i])+f[c[i-1]][d[i]]*k[i]+dp[i-1][j][0];
                    continue;
                }
                dp[i][j][0]=min(
                    dp[i-1][j][0]+f[c[i-1]][c[i]],
                    dp[i-1][j-1][1]+f[d[i-1]][c[i]]*(k[i-1])+f[c[i-1]][c[i]]*(1-k[i-1])
                );
                dp[i][j][1]=min(
                    f[c[i-1]][c[i]]*(1-k[i])+f[c[i-1]][d[i]]*k[i]+dp[i-1][j][0],
                    (f[d[i-1]][c[i]]*(k[i-1])+f[c[i-1]][c[i]]*(1-k[i-1]))*(1-k[i])+(f[d[i-1]][d[i]]*(k[i-1])+f[c[i-1]][d[i]]*(1-k[i-1]))*k[i]+dp[i-1][j-1][1]
                );
            }
        }
        #undef f
    //    printf("%.3f",min(f[n][j][]))
        double ans=1e10;
        for(int j=0;j<=m;++j){
            ans=min(ans,dp[n][j][0]);
            if(j!=m) ans=min(ans,dp[n][j][1]);
        }
        printf("%.2lf
    ",ans);
        return 0;
    }
    
    void floyd(){
        for(int k=1;k<=v;++k)
            for(int i=1;i<=v;++i)
                for(int j=1;j<=v;++j)
                    map[i][j]=min(map[i][k]+map[k][j],map[i][j]);
        return ;
    }
    
    void init_dp(){
        for(int i=0;i<2005;++i)
            for(int j=0;j<2005;++j)
                dp[i][j][0]=dp[i][j][1]=1e8;
    }
    丑代码
  • 相关阅读:
    docker 安装mysql
    Java web项目搭建系列之二 Jetty下运行项目
    Java web项目搭建系列之一 Eclipse中新建Maven项目
    Maven 添加其他Maven组件配置问题
    C# 中定义扩展方法
    Oracle 函数
    【Webservice】2 counts of IllegalAnnotationExceptions Two classes have the same XML type name
    Linux精简版系统安装网络配置问题解决
    Rsync 故障排查整理
    Failed to set session cookie. Maybe you are using HTTP instead of HTTPS to access phpMyAdmin.
  • 原文地址:https://www.cnblogs.com/JiuPleber/p/9893382.html
Copyright © 2011-2022 走看看