zoukankan      html  css  js  c++  java
  • [BZOJ4720][NOIP2016] 换教室

    link

    $solution:$

    考虑 $f(i,j,k)$ 表示前 $i$ 个时间中申请 $j$ 个的最小距离期望,且是否申请。

    然后分别讨论 $i-1$ 与$i$ 换还是不换且是否成功即可。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<climits>
    using namespace std;
    inline int read(){
        int f=1,ans=0;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
        return f*ans;
    }
    const int N=2001;
    const int M=2001;
    const int MAXN=2001;
    int head[MAXN],n,m,v,e,cnt;
    struct node{
        int u,v,w,nex;
    }x[180001];
    priority_queue<pair<int,int> > que;
    void add(int u,int v,int w){
        x[cnt].u=u,x[cnt].v=v,x[cnt].w=w,x[cnt].nex=head[u],head[u]=cnt++;
    }
    int A[MAXN],B[MAXN],dis[MAXN],Dis[MAXN][MAXN],vis[MAXN];
    double p[MAXN],f[N][M][2];
    void dijkstra(int S){
        memset(vis,0,sizeof(vis));
        memset(dis,127/3,sizeof(dis));dis[S]=0;
        que.push(make_pair(0,S));
        while(!que.empty()){
            int xx=que.top().second;que.pop();
            if(vis[xx]) continue;
            Dis[S][xx]=dis[xx];
            vis[xx]=1;
            for(int i=head[xx];i!=-1;i=x[i].nex){
                if(dis[x[i].v]>dis[xx]+x[i].w){
                    dis[x[i].v]=dis[xx]+x[i].w;
                    que.push(make_pair(-dis[x[i].v],x[i].v));
                }
            }
        }return;
    }
    int main(){
        //freopen("2.in","r",stdin);
        memset(head,-1,sizeof(head));
        n=read(),m=read(),v=read(),e=read();
        for(int i=1;i<=n;i++) A[i]=read();
        for(int i=1;i<=n;i++) B[i]=read();
        for(int i=1;i<=n;i++) scanf("%lf",&p[i]);
        memset(Dis,127/3,sizeof(Dis));
        for(int i=1;i<=v;i++) Dis[i][i]=0;
        for(int i=1;i<=e;i++){int u=read(),v=read(),w=read();Dis[u][v]=min(Dis[u][v],w);Dis[v][u]=Dis[u][v];}
        for(int k=1;k<=v;k++)
            for(int i=1;i<=v;i++)
                for(int j=1;j<=v;j++) Dis[i][j]=min(Dis[i][j],Dis[i][k]+Dis[k][j]);
        for(int i=1;i<=n;i++) dijkstra(i);
        for(int i=0;i<=n;i++)
            for(int j=0;j<=m;j++) f[i][j][0]=f[i][j][1]=(double)INT_MAX;
        double minn=f[0][0][0];
        f[1][0][0]=0,f[1][1][1]=0;
        for(int i=2;i<=n;i++){
            for(int j=0;j<=m;j++){
                f[i][j][0]=min( f[i-1][j][1]+ p[i-1]*Dis[B[i-1]][A[i]] + (1-p[i-1])*Dis[A[i-1]][A[i]] , f[i-1][j][0]+Dis[A[i-1]][A[i]] );
                if(j!=0) f[i][j][1]=min( f[i-1][j-1][1] + p[i-1]*p[i]*Dis[B[i-1]][B[i]] + p[i-1]*(1-p[i])*Dis[B[i-1]][A[i]] + (1-p[i-1])*p[i]*Dis[A[i-1]][B[i]] + (1-p[i-1])*(1-p[i])*Dis[A[i-1]][A[i]],f[i-1][j-1][0] + p[i]*Dis[A[i-1]][B[i]] + (1-p[i])*Dis[A[i-1]][A[i]]);
                //printf("f(%d,%d,0):%.3lf f(%d,%d,1):%.3lf
    ",i,j,f[i][j][0],i,j,f[i][j][1]);
            }
        }
        //for(int i=0;i<=m;i++) printf("%.2lf %.2lf
    ",f[n][i][0],f[n][i][1]);
        for(int i=0;i<=m;i++) minn=min(minn,min(f[n][i][0],f[n][i][1]));
        printf("%.2lf
    ",minn);
        return 0;
    }/*
    3 2 3 3
    2 1 2
    1 2 1
    0.8 0.2 0.5 
    1 2 5
    1 3 3
    2 3 1
    */
    View Code
  • 相关阅读:
    python timeit模块用法
    boto3库限速
    golang-Beego-orm创建的坑
    Java07
    Java06
    Java04
    Java03
    c
    Mac 安装GCC
    命令: go build
  • 原文地址:https://www.cnblogs.com/si-rui-yang/p/10847147.html
Copyright © 2011-2022 走看看