列表

详情


NC203371. 圆桌聚餐

描述

在一个餐馆中,有一个巨大的圆桌,共有 n 个座位。A国和B国计划在这个餐馆举行盛大的圆桌聚餐。
A国人很腼腆,不会主动坐在别人旁边;B国人更甚,并如果座位两边的各两个座位已经有人,他便绝不落座。
形式化的说,如果选中了 i ,并且 i-1,i+1中有至少一个座位有人,A国人不会落座。如果选中了 i ,并且 i-1,i-2, i+1,i+2四个座位中有至少一个座位有人,B国人不会落座,
A国和B国人在餐馆门口排起了长队(人数无限多),现在你知道每次进来一个人,是A国人概率是,是B国人的概率是。 对于每一个来到餐厅的人,他会使用选座机随机分配圆桌上的一个位置,位置被选中的概率均为(可能有人),如果这个位置不符合上述规则,或者已经有人就座了,他会直接离开餐馆,不然,他会坐在这个位置。

直到没有人能够再进入餐馆就座为止,期望多少人会落座?对 998244353取模输出。

输入描述

一行三个整数,n , p , q。

输出描述

一行一个整数,输出答案。
可以证明答案可以表示为 ( P 和 Q 为整数且互质, )。
输出 .

示例1

输入:

5 1 0

输出:

2

说明:

答案为2.

示例2

输入:

6 1 1

输出:

499122179

说明:

答案为2.5.

原站题解

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

C++14(g++5.4) 解法, 执行用时: 64ms, 内存消耗: 2912K, 提交时间: 2020-03-21 19:03:39

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=998244353,maxn=300050;
int dp[maxn],sum[maxn];
ll qpow(ll a,int n=mod-2)
{
	ll res=1;
    a%=mod;
	while(n)
	{
		if(n&1)	res=res*a%mod;
		a=a*a%mod; 
		n>>=1;
	}
	return res;
}
int main()
{
	int n,p,q;
	scanf("%d%d%d",&n,&p,&q);
	for(int i = 1; i <= n; sum[i]=(sum[i-1]+dp[i])%mod, dp[i]++, i++)
        dp[i] = ((i>5)*q*(2ll*sum[i-3]+i-5)+(i>3)*p*(2ll*sum[i-2]+i-3))%mod*qpow((i>5)*(i-5ll)*q+(i>3)*(i-3ll)*p)%mod;
    printf("%d\n",dp[n]);
	return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 63ms, 内存消耗: 2784K, 提交时间: 2020-03-22 14:04:46

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=998244353,maxn=300050;
int dp[maxn],sum[maxn];
ll qpow(ll a,int n=mod-2)
{
	ll res=1;
	a%=mod;
	while(n)
	{
		if(n&1) res=res*a%mod;
		a=a*a%mod;
		n>>=1;
	 } 
	 return res;
}
int main()
{
	int n,p,q;
	scanf("%d%d%d",&n,&p,&q);
	for(int i=1;i<=n;sum[i]=(sum[i-1]+dp[i])%mod,dp[i]++,i++)
	dp[i]=((i>5)*q*(2ll*sum[i-3]+i-5)+(i>3)*p*(2ll*sum[i-2]+i-3))%mod*qpow((i>5)*(i-5ll)*q+(i>3)*(i-3ll)*p)%mod;
	printf("%d\n",dp[n]);
	return 0;
}

上一题