首页 > 代码库 > 「美团 CodeM 初赛 Round B」景区路线规划 概率DP

「美团 CodeM 初赛 Round B」景区路线规划 概率DP

题意

游乐园被描述成一张 n 个点,m 条边的无向图(无重边,无自环)。每个点代表一个娱乐项目,第 i 个娱乐项目需要耗费 ci 分钟的时间,会让小 y 和妹子的开心度分别增加 h1i ,h2i ,他们俩初始的开心度都是 0 。每条边代表一条路,第 i 条边连接编号为 xi , yi 的两个娱乐项目,从 xi 走到 yi 或者从 yi 走到 xi 耗费的时间都是 ti 分钟。小 y 和妹子预计在游乐园里玩 k 分钟。最开始的时候,小 y 和妹子会等概率的随机选择一个娱乐项目开始玩,每玩完一个项目后,小 y 和妹子会等概率的随机选择一个可以从当前项目直达的且来得及玩的项目作为下一个项目。如果玩完一个项目后周围没有可以直达的且来得及玩的项目,小 y 和妹子就会提前结束游玩。 请你分别计算小 y 和妹子在游玩结束后开心度的期望。

数据

输入第一行给出三个空格隔开的整数,分别表示 n,m,k
接下来的 n 行,每行三个空格隔开的整数,分别表示 ci,h1i,h2i
接下来的 m 行,每行三个空格隔开的整数,分别表示 xi,yi,ti

输出两个用空格隔开的实数,分表表示小 y 和妹子开心度的期望,精确到小数点后 5 位。

0<n≤100,1×60≤k≤8×60

10≤ci≤60,0<h1i,h2i≤100

0<ti≤15

输入

5 4 60
25 12 83
30 38 90
16 13 70
22 15 63
50 72 18
2 1 7
3 1 7
4 3 1
5 3 10

输出

39.20000 114.40000

 

题解:

  设定pair<double ,double> dp[i][j],表示到达并玩完第 i 个项目,两个人的期望

  转移就是向能走的点,走下去,期望总和/cnt,就是累积的ans

  看代码吧

#include<bits/stdc++.h>using namespace std;#pragma comment(linker, "/STACK:102400000,102400000")#define ls i<<1#define rs ls | 1#define mid ((ll+rr)>>1)#define pii pair<int,int>#define MP make_pairtypedef long long LL;const long long INF = 1e18+1LL;const double pi = acos(-1.0);const int N = 5e2+5, M = 1e3+20,inf = 2e9+10;int n,m,K,t = 1,c[N],h1[N],h2[N],head[N];struct ss{    int to,next,value;}e[N*N];void add(int u,int v,int w) {    e[t].to = v;    e[t].next = head[u];    e[t].value = w;    head[u] = t++;}pair<double , double> dp[N][500];int vis[N][500];pair<double , double> dfs(int u,int k) {    if(vis[u][k])        return dp[u][k];    vis[u][k] = 1;    pair<double , double>& ret = dp[u][k],now;    ret = MP(h1[u],h2[u]);    int cnt = 0;    for(int i = head[u]; i; i = e[i].next) {        int to = e[i].to;        if(k >= c[to]+e[i].value)cnt++;    }    for(int i = head[u]; i; i = e[i].next) {        int to = e[i].to;        if(k < c[to] + e[i].value) continue;        now = dfs(to,k - c[to] - e[i].value);        ret.first += now.first*1.0/cnt;        ret.second += now.second*1.0/cnt;    }    //cout<<ret.first<<" "<<ret.second<<" "<<dp[u][k].first<<" "<<dp[u][k].second<<endl;    return ret;}int main() {    scanf("%d%d%d",&n,&m,&K);    for(int i = 1; i <= n; ++i)        scanf("%d%d%d",&c[i],&h1[i],&h2[i]);    for(int i = 1; i <= m; ++i) {        int x,y,t;        scanf("%d%d%d",&x,&y,&t);        add(x,y,t);add(y,x,t);    }    pair<double , double> ans = MP(0,0),now;    for(int i = 1; i <= n; ++i) {        now = dfs(i,K - c[i]);        ans.first += now.first*1.0/n;        ans.second += now.second*1.0/n;    }    printf("%.5f %.5f\n",ans.first,ans.second);    return 0;}

 

「美团 CodeM 初赛 Round B」景区路线规划 概率DP