NOIP2016Day1T3换教室(floyd+期望dp)

  啊。。。这个时间写博客,明天还要上学,整个人都不好了。。。

  这是我写的第一道期望题hiahiahia。。。

  题目大意就不说了QWQ

  80分儿做法:先floyd,爆搜枚举哪些点取,求出答案,效率O(C(n,m)*n)。

  100分:先floyd跑出两两点之间的距离,然后f[i][j][0/1]表示第i个时间,申请了j次换教室,0表示这个时间不申请,1表示这个时间申请,则有:

  f[i+1][j][0]=min(f[i][j][0]+dis[a[i]][a[i+1]],f[i][j][1]+dis[b[i]][a[i+1]]*pro[i]+dis[a[i]][a[i+1]]*(1-pro[i]));

  f[i+1][j+1][1]=min(f[i][j][1]+dis[a[i]][a[i+1]]*(1-pro[i])*(1-pro[i+1])+dis[b[i]][a[i+1]]*pro[i]*(1-pro[i+1])

            +dis[a[i]][b[i+1]]*(1-pro[i])*pro[i+1]+dis[b[i]][b[i+1]]*pro[i]*pro[i+1],

            f[i][j][0]+dis[a[i]][a[i+1]]*(1-pro[i+1])+dis[a[i]][b[i+1]]*pro[i+1]);

  一开始freopen没删掉WA了好几次心态都崩了>_<

代码如下:

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
using namespace std;
int a[2010],b[2010],dis[310][310],n,m,v,e,x,y,z;
double pro[2010],f[2010][2010][2],ans;
int main()
{
    scanf("%d %d %d %d",&n,&m,&v,&e);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    for(int i=1;i<=n;i++)scanf("%d",&b[i]);
    for(int i=1;i<=n;i++)scanf("%lf",&pro[i]);
    for(int i=1;i<=v;i++)for(int j=1;j<=v;j++)if(i!=j)dis[i][j]=233333333;
    for(int i=1;i<=e;i++)scanf("%d%d%d",&x,&y,&z),dis[y][x]=dis[x][y]=min(dis[x][y],z);
    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=0;i<=n;i++)for(int j=0;j<=min(i,m);j++)f[i][j][0]=f[i][j][1]=23333333333.0;
    f[0][0][0]=0;
    for(int i=0;i<n;i++)for(int j=0;j<=min(i,m);j++)
    {
        f[i+1][j][0]=min(f[i][j][0]+dis[a[i]][a[i+1]],f[i][j][1]+dis[b[i]][a[i+1]]*pro[i]+dis[a[i]][a[i+1]]*(1-pro[i]));
        if(j==m)continue;
        f[i+1][j+1][1]=f[i][j][1]+dis[a[i]][a[i+1]]*(1-pro[i])*(1-pro[i+1])+dis[b[i]][a[i+1]]*pro[i]*(1-pro[i+1]);
        f[i+1][j+1][1]+=dis[a[i]][b[i+1]]*(1-pro[i])*pro[i+1]+dis[b[i]][b[i+1]]*pro[i]*pro[i+1];
        f[i+1][j+1][1]=min(f[i+1][j+1][1],f[i][j][0]+dis[a[i]][a[i+1]]*(1-pro[i+1])+dis[a[i]][b[i+1]]*pro[i+1]);
    }
    ans=23333333333.0;
    for(int i=0;i<=m;i++)
    ans=min(ans,min(f[n][i][0],f[n][i][1]));
    printf("%.2lf
",ans);
}
View Code
原文地址:https://www.cnblogs.com/Sakits/p/6436208.html