列表

详情


NC13250. 景区路线规划

描述

美团旅行团队最近打算推出一项新服务,为景区的各个景点规划游览路线,提升游客满意度。其中一个重要的问题是对于一个景区道路网,求出游客的满意度的期望值。基于用户的喜好差异,我们需要对男性游客和女性游客的满意度分别计算。
景区被描述成一张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

输出:

39.20000 114.40000

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 29ms, 内存消耗: 988K, 提交时间: 2020-06-23 19:37:05

#include<bits/stdc++.h>
#define Fox ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
const int N=105;
int n,m,K,x,y,t,tot;
int c[N],h[N][2];
int head[N],ver[N*N],nxt[N*N],edge[N*N];
double dp[500][N];
void add(int x,int y,int z){
	edge[++tot]=z;ver[tot]=y;
	nxt[tot]=head[x];head[x]=tot;
}
double solve(int x){
	double ans=0;
	memset(dp,0,sizeof(dp));
	for(int i=K;i;i--){
		for(int j=1;j<=n;j++){
			int s=0;
			for(int k=head[j];k;k=nxt[k])
				if(i+edge[k]<=K)s++;
			for(int k=head[j];k;k=nxt[k])
				if(i+edge[k]<=K)dp[i][j]+=(dp[i+edge[k]][ver[k]]/s);
			dp[i][j]+=h[j][x];
		}
	}
	for(int i=1;i<=n;i++)ans+=dp[c[i]][i]/n;
	return ans;
}
int main(){
	Fox;
	scanf("%d%d%d",&n,&m,&K);
	for(int i=1;i<=n;i++)scanf("%d%d%d",&c[i],&h[i][0],&h[i][1]);
	for(int i=1;i<=m;i++){
		scanf("%d%d%d",&x,&y,&t);
		add(x,y,t+c[y]);
		add(y,x,t+c[x]);
	}
	printf("%.5lf %.5lf",solve(0),solve(1));
    return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 55ms, 内存消耗: 1320K, 提交时间: 2020-04-17 16:38:55

#include<cstdio>
#include<iostream>
using namespace std;

const int N=111;
struct node{int c,h[3];}a[N];
int n,m,k,e[N][N];double ans[3],f[3][N][510];

double dfs(int id,int t,int v){
  if(f[v][id][t])return f[v][id][t];
  double sum=0;int cnt=0;
  for(int i=1;i<=n;i++){
    if(e[id][i]&&t>=e[id][i]+a[i].c){
      cnt++;sum+=dfs(i,t-e[id][i]-a[i].c,v);
    }
  }
  if(cnt>0)sum/=cnt;
  sum+=a[id].h[v];f[v][id][t]=sum;
  return sum;
}

int main(){
  scanf("%d%d%d",&n,&m,&k);
  for(int i=1;i<=n;i++){
    scanf("%d%d%d",&a[i].c,&a[i].h[1],&a[i].h[2]);
  }
  for(int i=1,x,y,z;i<=m;i++){
    scanf("%d%d%d",&x,&y,&z);e[x][y]=e[y][x]=z;
  }
  for(int i=1;i<=2;i++){
    for(int j=1;j<=n;j++){
      if(k>=a[j].c){ans[i]+=dfs(j,k-a[j].c,i);}
    }
  }
  ans[1]/=n;ans[2]/=n;
  printf("%.5f %.5f\n",ans[1],ans[2]);
  return 0;
}

上一题