noip 2016 换教室

Posted miracevin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了noip 2016 换教室相关的知识,希望对你有一定的参考价值。

第一个 完全自己想的期望+完全自己做的T3    并且  +1遍AC

Description:

luogu 换教室

Solution:

一看是一道期望题。

再一看,发现,v<=300,n,m<=2000有点意思。

大概复杂度n^2确定。

有一张图?任意两点间最短路?300就是floyd的提示嘛!!

预处理floyd确定。

发现,阶段比较明显,第i个阶段

一看就是一道期望dp题了。

dp状态:显然要记录第i阶段,显然要知道用了几个申请。恰好n方开的下。

可以设dp[i][j],表示前i阶段,包括这个阶段用了j个申请,期望值的最小值。

但是,不知道可能会在哪里,根本无法转移。

 

就设dp[i][j][0/1]表示,前i阶段,包括这个阶段用了j个申请,这一次有没有用申请。(仅有没有,过不过不知道。)

这样就可以转移了。

因为,知道了在哪里。

如果上一次没有用,就在c[i-1],否则一定概率在d[i-1]一定概率在 c[i-1]

转移的时候,当前是0,1同理处理一下概率即可。

 

注意,本质上,dp的转移思想还是,从上一个状态选择一个方案,算出这个转移的代价,取最小的转移过来。

所以,min肯定是在外面的。

至于期望的转移是否正确,就审查一下是否所有的情况概率和是1就好啦~!

 

Code:

#include<bits/stdc++.h>
using namespace std;
const int N=2000+3;
const int M=300+3;
const int inf=0x3f3f3f3f;
const double big=1000000007.00;
int dis[M][M];
int c[N],d[N];
double f[N][N][2];
double p[N];
int n,m,v,e;
int main()
{
    scanf("%d%d%d%d",&n,&m,&v,&e);
    for(int i=1;i<=n;i++) scanf("%d",&c[i]);
    for(int i=1;i<=n;i++) scanf("%d",&d[i]);
    for(int i=1;i<=n;i++) scanf("%lf",&p[i]);
    int x,y,z;
    memset(dis,inf,sizeof dis);
    for(int i=1;i<=e;i++){
        scanf("%d%d%d",&x,&y,&z);
        if(x==y) continue;
        dis[x][y]=min(dis[x][y],z);
        dis[y][x]=dis[x][y];
    }
    for(int k=1;k<=v;k++){
      dis[k][k]=0;
      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++){
        for(int j=0;j<=m;j++)
         f[i][j][0]=f[i][j][1]=big;
    }
    
    f[1][0][0]=0.0;
    f[1][1][1]=0.0;
    
    for(int i=2;i<=n;i++){
        for(int j=0;j<=min(i,m);j++){
            f[i][j][0]=min(f[i-1][j][0]+dis[c[i-1]][c[i]],
                        f[i-1][j][1]+p[i-1]*dis[d[i-1]][c[i]]+(1.00-p[i-1])*dis[c[i-1]][c[i]]); 

            if(j>=1) 
            f[i][j][1]=min(
            
            (1.00-p[i])*(f[i-1][j-1][0]+dis[c[i-1]][c[i]])+
            p[i]*(f[i-1][j-1][0]+dis[c[i-1]][d[i]]),
            
            (1.00-p[i])*(f[i-1][j-1][1]+p[i-1]*dis[d[i-1]][c[i]]+(1.00-p[i-1])*dis[c[i-1]][c[i]])+
            p[i]*(f[i-1][j-1][1]+p[i-1]*dis[d[i-1]][d[i]]+(1.00-p[i-1])*dis[c[i-1]][d[i]])
            
            );

        }
    }
    double ans=big;
    for(int j=0;j<=m;j++){
        ans=min(ans,min(f[n][j][0],f[n][j][1]));
    }
    printf("%.2lf",ans);
    return 0;
}

 

以上是关于noip 2016 换教室的主要内容,如果未能解决你的问题,请参考以下文章

uoj262 NOIP2016—换教室

[NOIp2016提高组]换教室

noip 2016 换教室

[NOIP2016提高组]换教室

[NOIP2016]换教室 题解(奇怪的三种状态)

[NOIp 2016]换教室