zoukankan      html  css  js  c++  java
  • 期望DP入门(p1850换教室)

    第一个,期望dp所有的情况一定要考虑好,每个现状态都由前一个状态转移而来,所以无论是前一个状态通过怎样的方式,两状态的起点终点如何,都应加在一起。此题关系到前一个是否成功和后一个是否成功,分别为

    i-1决定换教室,i决定换教室时 (i-1成功换教室+i失败换教室) (i-1成功换教室+i成功换教室) (i-1失败换教室+i失败换教室) (i-1失败换教室+i成功换教室)

    i-1决定换教室,i决定不换教室(i-1成功换教室+i不换教室) (i-1失败换教室+i不换教室) 

    i-1决定不换教室,i决定换教室 (i-1不换教室+i成功换教室) (i-1不换教室+i失败换教室)

    i-1决定不换教室,i决定不换教室 (i-1不换教室+i不换教室)

    第二个,memset是绝对tmd不能用在double型数组上的。你会si掉。

    第三个,判重边邻接矩阵可以简单这样搞:dis[x][y]=dis[y][x]=min(z,dis[x][y]);如果遇见vector或链式前向星或邻接矩阵都可以:map <pair<int,int>,bool> q;if(q[make_pair(a,b)]) continue;

    第四个, double型的读入为%lf而非%llf。(被坑惨了)

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    int n,m,v,e,dis[302][302],a[2003],b[2003],x,y,z;
    double k[2003],a2,a3,f[2003][2003][2];
    
    void foll(){
        for(int k=1;k<=v;k++)
            for(int i=1;i<=v;i++)
                for(int j=1;j<=v;j++)
                    if(dis[i][j]>dis[i][k]+dis[k][j])
                        dis[i][j]=dis[i][k]+dis[k][j];
    }
    
    void DP(){
        for(int i=2;i<=n;i++){
            for(int j=0;j<=min(i,m);j++){
                int m1=dis[a[i-1]][a[i]],m2=dis[a[i-1]][b[i]],m3=dis[b[i-1]][a[i]],m4=dis[b[i-1]][b[i]];
                f[i][j][0]=min(f[i-1][j][1]+m3*k[i-1]+m1*(1-k[i-1]),f[i-1][j][0]+m1);
                if(j>=1)
                    f[i][j][1]=min(f[i-1][j-1][1]+m4*k[i-1]*k[i]+m2*(1-k[i-1])*k[i]+m1*(1-k[i-1])*(1-k[i])+m3*k[i-1]*(1-k[i]),f[i-1][j-1][0]+dis[a[i-1]][b[i]]*k[i]+dis[a[i-1]][a[i]]*(1-k[i]));
            }
        }
    }
    
    int main(){
        scanf("%d%d%d%d",&n,&m,&v,&e);
        for(int i=1;i<=300;i++)
            for(int j=1;j<=300;j++)    dis[i][j]=99999999;
        for(int i=1;i<=300;i++)    dis[i][i]=0;
        
        for(int i=1;i<=n;i++)
            for(int j=0;j<=m;j++)
                f[i][j][1]=f[i][j][0]=99999999;
        f[1][0][0]=f[1][1][1]=f[1][1][0]=0;
        for(int i=1;i<=n;i++)    scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)    scanf("%d",&b[i]);
        for(int i=1;i<=n;i++)    scanf("%lf",&k[i]);
        for(int i=1;i<=e;i++){
            scanf("%d%d%d",&x,&y,&z);
            dis[x][y]=dis[y][x]=min(z,dis[x][y]);
        }
    
        foll();
        DP();
        double ans=99999999;
        for(int i=0;i<=m;i++)
            ans=min(ans,min(f[n][i][1],f[n][i][0]));
        printf("%.2lf",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    Redis缓存穿透、缓存雪崩、redis并发问题 并发竞争key的解决方案 (阿里)
    CAP原则 (阿里)
    分布式系统一致性问题解决实战(阿里) 异步解耦+消息队列可作为分布式系统满足最终一致性的优秀方案
    高并发&高可用系统的常见应对策略 秒杀等-(阿里)
    Redis的内存回收策略和内存上限(阿里)
    如何保证MQ的顺序性?比如Kafka
    spring的controller默认是单例还是多例
    HashMap线程不安全的体现
    TCP的三次握手与四次挥手
    常见排序算法及对应的时间复杂度和空间复杂度
  • 原文地址:https://www.cnblogs.com/jindui/p/11378070.html
Copyright © 2011-2022 走看看