美团codeM预赛B 景区路线规划

本文介绍了一种用于旅游景区路线规划的算法实现,旨在提高游客的游览体验。该算法通过动态规划计算男性游客和女性游客在有限时间内游览各景点所能获得的最大满意度期望值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 景区路线规划

时间限制:1秒

空间限制:32768K

美团旅行团队最近打算推出一项新服务,为景区的各个景点规划游览路线,提升游客满意度。其中一个重要的问题是对于一个景区道路网,求出游客的满意度的期望值。基于用户的喜好差异,我们需要对男性游客和女性游客的满意度分别计算。
景区被描述成一张n个点、m条边的无向图(无重边,无自环)。每个点代表一个景点,第i个景点游览需要耗费ci分钟,会让男性游客和女性游客的满意度分别增加h1i和h2i(满意度初始值都为0)。每条边代表一条路,第i条边连接编号为xi,yi的两个景点,从景点xi走到yi和从yi走到xi的时间都是ti分钟。
每个游客在景区中最长可以游览k分钟,最开始会随机的通过不同大门进入到一个景点开始游览,每游览完一个项目,游客会等概率随机选择一个可以从当前景点直达且来得及游览的景点作为下一个游览目标(已经游览过的景点也会因为有各种新活动而让游客再次考虑,所以我们这里不区分景点是否已经游览过)。如果游览完一个景点后,周围没有来得及游览的景点,本次游玩就结束了。
请你分别计算小y和妹子在游玩结束后开心度的期望。 
输入描述:
第一行给出三个空格隔开的整数,分别表示n, m, k(0 < n ≤ 100, 1 * 60 ≤ k ≤ 8 * 60)
接下来的n行,每行三个空格隔开的整数,分别表示ci, h1i, h2i (10 ≤ ci ≤ 60,0 < h1i, h2i ≤ 100)
接下来的m行,每行三个空格隔开的整数,分别表示xi, yi, ti (0 < ti ≤ 15)


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

输入例子1:
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

输出例子1:
39.20000 114.40000
解题思路:用dp[i][j]表示时间点j在地点i的概率


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <stack>
#include <cmath>
#include <map>
#include <bitset>
#include <set>
#include <vector>
#include <functional>

using namespace std;

#define LL long long
const int INF = 0x3f3f3f3f;

int n,m,t;
int c[105],h1[105],h2[105];
int s[105],nt[20009],e[20009],w[20009];
double dp[105][60*8+5];

double f(int h[])
{
    double ans=0;
    for(int i=1; i<=n; i++)
        for(int j=0; j<=t; j++) dp[i][j]=0;
    for(int i=1; i<=n; i++) dp[i][c[i]]=1.0/n;
    for(int i=0; i<=t; i++)
    {
        for(int j=1; j<=n; j++) ans+=dp[j][i]*h[j];
        for(int j=1; j<=n; j++)
        {
            int sum=0;
            for(int k=s[j];~k; k=nt[k])
                if(t-i>=w[k]+c[e[k]]) sum++;
            if(sum==0) continue;
            for(int k=s[j];~k; k=nt[k])
                if(t-i>=w[k]+c[e[k]]) dp[e[k]][i+w[k]+c[e[k]]]+=dp[j][i]/sum;
        }
    }
    return ans;
}

int main()
{
    while(~scanf("%d%d%d",&n,&m,&t))
    {
        memset(s,-1,sizeof s);
        for(int i=1; i<=n; i++) scanf("%d%d%d",&c[i],&h1[i],&h2[i]);
        int cnt=1;
        for(int i=1; i<=m; i++)
        {
            int u,v,ww;
            scanf("%d%d%d",&u,&v,&ww);
            nt[cnt]=s[u],s[u]=cnt,e[cnt]=v,w[cnt++]=ww;
            nt[cnt]=s[v],s[v]=cnt,e[cnt]=u,w[cnt++]=ww;
        }
        printf("%.5lf %.5lf\n",f(h1),f(h2));
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值