NOIP2016换教室

Description

Click here

Analysis

不得不承认看了题之后确实想到的是概率dp。。。

由于博主太懒而且这篇题解挺详细

我就只记录一下没讲到的地方


 

f[i][j][1/0]是上了i节课,当前换了j次(包括本节课)教室的本节课的选择(0/1)

只给f[1][1][1],[1][0][0]两项赋初值为0

强调一下f[i][j][k]是已经上了i节课,换了j次教室(包括第i节课),这节课是否换教室

所以只有上第一节课换教室(f[1][1][1])和不换教室(f[1][0][0])两种情况要初始化且初始化为0

注意循环中j=0要分开

代码

#include<cstdio>
#include<iostream>
using namespace std;
const int INF=800000000;
int n,m,v,e;
int c[2005],d[2005],dis[305][305];
double k[2005],f[2005][2005][2];
inline int read(){
	int x=0;char ch=getchar();
	while(ch<'0'||ch>'9')ch=getchar();
	while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	return x;
}
int main(){
    scanf("%d%d%d%d",&n,&m,&v,&e);
    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++)cin>>k[i];
    for (int i=1;i<=v;i++)
        for (int j=1;j<i;j++)
            dis[j][i]=dis[i][j]=INF;
    for(int i=1;i<=e;i++){
        int cn=read(),cm=read(),cw=read();
        dis[cn][cm]=dis[cm][cn]=min(dis[cn][cm],cw);
    }
    //输入
    for(int l=1;l<=v;l++){
        for(int i=1;i<=v;i++){
            for(int j=1;j<i;j++){
                if(dis[i][j]>dis[i][l]+dis[l][j])
                dis[j][i]=dis[i][j]=dis[i][l]+dis[l][j];
            }
        }
    }
    //Floyd
    for(int i=1;i<=n;i++){
        for(int j=0;j<=m;j++){
            f[i][j][0]=f[i][j][1]=INF;
        }
    }
    f[1][1][1]=f[1][0][0]=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]+ k[i-1]*dis[d[i-1]][c[i]]+ (1-k[i-1])*dis[c[i-1]][c[i]], 
                            f[i-1][j][0] +dis[c[i-1]][c[i]]);
            if (j!=0)
                f[i][j][1]=min(f[i-1][j-1][1]+k[i-1]*k[i]*dis[d[i-1]][d[i]]+k[i-1]*(1-k[i])*dis[d[i-1]][c[i]]+(1-k[i-1])*k[i]*dis[c[i-1]][d[i]]+(1-k[i-1])*(1-k[i])*dis[c[i-1]][c[i]],
                            f[i-1][j-1][0]+k[i]*dis[c[i-1]][d[i]]+(1-k[i])*dis[c[i-1]][c[i]]);
        }
    //dp
    double ans=INF;
    for (int i=0;i<=m;i++)
        for (int j=0;j<=1;j++){
            ans=min(ans,f[n][i][j]);
        }
    printf("%.2lf",ans);
    return 0;
}
posted @ 2019-05-07 21:30  lqhsr  阅读(157)  评论(0编辑  收藏  举报