[概率期望]做题记录-换教室

 

 

我的天这是什么DP鬼题……

写了一整节英语自习的式子,恶心吐了

然后调题也恶心死了……我的天

一开始先Floyed跑一遍最短路然后大力DP

注意初始化……不说了让我吐会

#include<cstdio>
#include<cstring>
#include<string>
#define WR WinterRain
#define int long long
using namespace std;
const int WR=2010,INF=2147483647;
int n,m,v,e;
int c[WR],d[WR];
int dis[WR][WR];
double k[WR],dp[WR][WR][2];
int read(){
    int s=0,w=1;
    char ch=getchar();
    while(ch>'9'||ch<'0'){
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        s=(s<<1)+(s<<3)+ch-48;
        ch=getchar();
    }
    return s*w;
}
signed main(){
    memset(dis,0x3f,sizeof(dis));
    n=read(),m=read(),v=read(),e=read();
    for(int i=1;i<=n;i++) c[i]=read();
    for(int i=1;i<=n;i++) d[i]=read();
    for(int i=1;i<=n;i++) scanf("%lf",&k[i]);
    for(int i=1;i<=e;i++){
        int u=read(),v=read(),w=read();
        dis[u][v]=dis[v][u]=min(dis[u][v],w);
    }
    for(int i=1;i<=v;i++){
        for(int j=1;j<=v;j++){
            for(int k=1;k<=v;k++){
                dis[j][k]=min(dis[j][k],dis[j][i]+dis[i][k]);
            }
        }
    }
    for(int i=1;i<=v;i++) dis[i][i]=dis[i][0]=dis[0][i]=0;
    for(int i=0;i<=n;i++){
        for(int j=0;j<=m;j++){
            dp[i][j][0]=dp[i][j][1]=(double)INF;
        }
    }
    dp[1][0][0]=dp[1][1][1]=0;
    for(int i=2;i<=n;i++){
        dp[i][0][0]=dp[i-1][0][0]+dis[c[i-1]][c[i]];
        for(int j=1;j<=i;j++){
            dp[i][j][0]=min(dp[i][j][0],min(dp[i-1][j][0]+dis[c[i-1]][c[i]],//上一次没有申请换也没有换
                        dp[i-1][j][1]+dis[c[i-1]][c[i]]*(1-k[i-1])+dis[d[i-1]][c[i]]*k[i-1]));
                        //上一次申请了没有通过加上上一次在对面教室申请通过
            dp[i][j][1]=min(dp[i][j][1],
                        min(dp[i-1][j-1][0]+dis[c[i-1]][c[i]]*(1-k[i])+dis[c[i-1]][d[i]]*k[i],
                        //上一次申请了没有通过加上上一次申请了而且通过了,去了对面教室
                        dp[i-1][j-1][1]+dis[d[i-1]][d[i]]*k[i]*k[i-1]
                        //上一次在对面教室申请了,通过了,直接去下一节课对面教室
                        +dis[c[i-1]][c[i]]*(1-k[i-1])*(1-k[i])
                        //上一次申请了这一次也申请了两次都没有通过
                        +dis[d[i-1]][c[i]]*k[i-1]*(1-k[i])
                        //上一次申请通过这一次申请没有
                        +dis[c[i-1]][d[i]]*(1-k[i-1])*k[i]));//上一次申请没有通过而这一次申请通过了
        }
    }
    double ans=(double)INF;
    for(int i=0;i<=m;i++) ans=min(ans,min(dp[n][i][0],dp[n][i][1]));
    printf("%.2lf",ans);
    return 0;
}

 

posted @ 2022-05-25 16:30  冬天丶的雨  阅读(22)  评论(0编辑  收藏  举报
Live2D