洛谷P1850 换教室

洛谷P1850 换教室

原题链接

设状态f[i][j]表示前i个时间段,申请了j次,且第i次不申请的最小代价期望,
g[i][j]表示前i个时间段,申请了j次,且第i次申请的最小代价期望,
然后转移

// It is made by XZZ
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
#define rep(a,b,c) for(rg int a=b;a<=c;a++)
#define drep(a,b,c) for(rg int a=b;a>=c;a--)
#define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
#define il inline
#define rg register
#define vd void
#define db double
typedef long long ll;
il int gi(){
    rg int x=0,f=1;rg char ch=getchar();
    while(ch<'0'||ch>'9')f=ch=='-'?-1:f,ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*f;
}
db u[302][302];
db f[2010][2010],g[2010][2010];
int c[2002],d[2002];
db k[2002];
int main(){
    // freopen("classrooma.in","r",stdin);
    // freopen("classrooma.out","w",stdout);
    int n=gi(),m=gi(),v=gi(),e=gi();
    rep(i,1,n)c[i]=gi();rep(i,1,n)d[i]=gi();
    rep(i,1,n)scanf("%lf",&k[i]);
    rep(i,1,v)rep(j,i+1,v)u[i][j]=u[j][i]=1e9;
    {
        int a,b;db c;
        while(e--){
            a=gi(),b=gi();
            scanf("%lf",&c);
            u[a][b]=u[b][a]=min(u[a][b],c);
        }
    }
    rep(l,1,v)rep(i,1,v)rep(j,1,v)u[i][j]=min(u[i][j],u[i][l]+u[j][l]);
    rep(i,0,n)rep(j,0,m)f[i][j]=g[i][j]=1e9;
    f[1][0]=g[1][1]=0;
    rep(i,2,n){
        f[i][0]=f[i-1][0]+u[c[i-1]][c[i]];
        rep(j,1,min(m,i)){
            f[i][j]=min(
                f[i-1][j]+
                u[c[i-1]][c[i]],
                
                g[i-1][j]+
                k[i-1]*u[d[i-1]][c[i]]+
                (1.0-k[i-1])*u[c[i-1]][c[i]]
            );
            g[i][j]=min(
                f[i-1][j-1]+
                k[i]*u[c[i-1]][d[i]]+
                (1-k[i])*u[c[i-1]][c[i]],
                
                g[i-1][j-1]+
                k[i]*k[i-1]*u[d[i-1]][d[i]]+
                k[i]*(1.0-k[i-1])*u[c[i-1]][d[i]]+
                k[i-1]*(1.0-k[i])*u[d[i-1]][c[i]]+
                (1.0-k[i])*(1.0-k[i-1])*u[c[i-1]][c[i]]
            );
        }
    }
    db ans=f[n][0];
    rep(i,1,m)ans=min(ans,min(f[n][i],g[n][i]));
    printf("%.2lf\n",ans);
    return 0;
}

我竟然没初始化数组mdzz...

posted @ 2017-08-21 14:26  菜狗xzz  阅读(213)  评论(0编辑  收藏  举报