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
  • 相关阅读:
    并发编程 之 生产者消费者模型
    并发编程 之 IPC机制
    Django + DRF + Elasticsearch 实现搜索功能
    时间上相邻query,前缀去重
    列表套字典,将字典元素去重
    K8s
    docker
    数据处理
    Django日志配配置
    Canvas 获取颜色值
  • 原文地址:https://www.cnblogs.com/jindui/p/11378070.html
Copyright © 2011-2022 走看看