[期望DP] LibreOJ #6178. [美团 CodeM 初赛 Round B] 景区路线规划 题解

(传送门)

题目大意

题目说的相当清楚了,不解释,点传送门。


解题分析

这道题就是利用期望的线性的性质来做。所以想到DP,但是正推会有点难,可以想到从x相邻的节点走到x的概率是不同的,但是从x走到相邻的节点概率是相同的,所以可以考虑逆向处理

f[i][j][0/1]:现在走到第i个景点,从j时刻开始走(配合倒推……),(小y/他的妹子)的开心度的期望值

则转移方程为(推的时候把0/1这一维省略掉,反正不会串)

f[i][j]+=f[son[j]][j+c[son[j]]+w[j]]/num,其中num为可以在时限内游玩完成且相邻的所有景点个数

#include<cstdio>
#include<cstring>
#define maxn 105
#define maxe 20005
#define maxv 60005
using namespace std;
int n,e,k,tot,son[maxe],nxt[maxe],w[maxe],lnk[maxn],c[maxn],a[maxn],b[maxn];
double ansx,ansy,f[105][505][2];
inline void readi(int &x){
    x=0; char ch=getchar();
    while ('0'>ch||ch>'9') ch=getchar();
    while ('0'<=ch&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
}
void _add(int x,int y,int z){
    tot++; son[tot]=y; w[tot]=z; nxt[tot]=lnk[x]; lnk[x]=tot;
}
int main()
{
    freopen("b.in","r",stdin);
    freopen("b.out","w",stdout);
    readi(n); readi(e); readi(k); tot=0; ansx=ansy=0.0;
    for (int i=1;i<=n;i++) {readi(c[i]); readi(a[i]); readi(b[i]);}
    for (int i=1,x,y,z;i<=e;i++){
        readi(x); readi(y); readi(z); _add(x,y,z); _add(y,x,z);
    }
    for (int ti=k;ti;ti--)
        for (int i=1,tem;i<=n;i++){
            tem=0; f[i][ti][0]=a[i]; f[i][ti][1]=b[i];
            for (int j=lnk[i];j;j=nxt[j]) tem+=(ti+w[j]+c[son[j]]<=k);
            for (int j=lnk[i];j;j=nxt[j]) if (ti+w[j]+c[son[j]]<=k)
            {f[i][ti][0]+=f[son[j]][ti+w[j]+c[son[j]]][0]/tem; f[i][ti][1]+=f[son[j]][ti+w[j]+c[son[j]]][1]/tem;}
        }
    for (int i=1;i<=n;i++) {ansx+=f[i][c[i]][0]/n; ansy+=f[i][c[i]][1]/n;}
    printf("%.5lf %.5lf",ansx,ansy);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/try__jhf/article/details/78244569
今日推荐