2022牛客五一集训派对day2 (C、E)

2022牛客五一集训派对day2 (C、E)

E Music Game

题目链接

​题目描述

Niuniu likes to play OSU!
We simplify the game OSU to the following problem.
Given n and m, there are n clicks. Each click may success or fail.
For a continuous success sequence with length X, the player can score X m X^m Xm.
The probability that the i-th click success is p[i]/100.
We want to know the expectation of score.
As the result might be very large (and not integral), you only need to output the result mod 1000000007.

题意

有n次点击每次点击成功的概率是p[i]/100,连续点击成功X次会获得X^m的分数,求分数的期望。(1 <= n <= 1000,1 <= m <= 1000,0 <= p[i] <= 100)

思路

首先,先预处理出来连续一段的概率和X^m的值,然后枚举端点i、j,表示区间[i,j]内连续成功点击(i,j可以相等),并且要乘上i-1和j+1失败的概率,这一段的期望就是(i-1失败的概率)*(j+1失败的概率)*([i,j]连续获胜的概率)*(分数)。

AC代码

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,a,n) for(int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
#define int long long
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
typedef double db;
const int mod=1000000007;
ll powmod(ll a,ll b) {ll res=1;a%=mod;assert(b>=0);for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
// head
const int MAXN=1000+100;
int n,m;
int p[MAXN],X[MAXN];
int pre[MAXN][MAXN];

int inv(int x){
	return powmod(x,mod-2);
}
void solve(){
	cin>>n>>m;
	rep(i,1,n+1) cin>>p[i],X[i]=powmod(i,m);
	rep(i,1,n+1){
		pre[i][i]=p[i]*inv(100)%mod;
		rep(j,i+1,n+1) 
			pre[i][j]=pre[i][j-1]*p[j]%mod*inv(100)%mod;
	}
	int ans=0;
	rep(i,1,n+1){
		rep(j,i,n+1){
			ans=(ans+pre[i][j]*X[j-i+1]%mod*(100-p[i-1])%mod*inv(100)%mod*(100-p[j+1])%mod*inv(100)%mod)%mod;
		}
	}
	cout<<ans<<endl;
}

signed main(){
	ios::sync_with_stdio(false);cin.tie(0);cin.tie(0);
	int _=1;
	while(_--) solve();
	return 0;
}

C All in

题目链接

​题目描述

Niuniu likes gambling.
Team A and B will play 2 n − 1 2n-1 2n1 matches.
Niuniu wants to bet 2 2 n − 1 2^{2n-1} 22n1 that team A wins the entire series.
In other words, if A wins n or more matches, Niuniu will gain 2 2 n − 1 2^{2n-1} 22n1.
If A loses(B wins) n or more matches, Niuniu will lose 2 2 n − 1 2^{2n-1} 22n1(gain - 2 2 n − 1 2^{2n-1} 22n1).

However, the banker does not allow such a bet. Niuniu can only bet on individual matches.
The winning percentage of both teams is 0.5. All matches are independent of each other.
Niuniu can bet on the (i+1)-th match after seeing the results of the first i games.
Your program need read n and output the bet on the first match.
Then read the result of the first match, output the bet on the second match.
Then read the result of the second match, output the bet on the third match.

Finally, read the result of the (……)-th match, and team A wins or loses the entire series, the program ends.
The answer can be uniquely determined, and this is not a interactive problem.
As the result might be very large, you should output the result mod 1000000007.

题意

给定一个n,进行 2 n − 1 2n-1 2n1场比赛,每一场比赛用0或者1表示,0代表这场A赢,1代表这场A输(B赢),需要一场一场的下注,如果A先赢下n场将会赢得 2 2 n − 1 2^{2n-1} 22n1,否则将会输掉 2 2 n − 1 2^{2n-1} 22n1。每一场双方赢的概率都是0.5,每一场都是相互独立的。当A赢的场次或者A输的场次达到n时,终止输入。每一行输出每一场比赛的赌注。(1 <= n <= 100000)。

思路

如果当前A的胜率为 p p p,那么下一场不管是A赢还是A输概率的变化幅度都是相等(队友告诉的),即A赢胜率为 p + q p+q p+q,A输胜率为 p − q p-q pq,然后会发现一件事情,当胜率增加时就会赢钱,胜率减少时就会输钱,也就是说下注的钱数是由胜率决定。我是通过样例发现,这一场的赌注就是 2 q ∗ 2 2 n − 1 2q*2^{2n-1} 2q22n1。(要是没有这么多的样例多半是寄了)。
如果胜率从0.5增加到1,就会赢 2 2 n − 1 2^{2n-1} 22n1
如果胜率从0.5减少到0,就会输 2 2 n − 1 2^{2n-1} 22n1
那么剩下的问题就是如何求出这个 q q q
假设当前A赢了 a a a场,B赢了 b b b场,那么就会剩下 l e f t = 2 ∗ n − 1 − a − b left=2*n-1-a-b left=2n1ab场(假设没有提前结束)。那么A获胜的概率就是 p = ∑ i = n − a l e f t C l e f t i 2 l e f t p=\frac{\sum_{i=n-a}^{left}{C_{left}^{i}}}{2^{left}} p=2lefti=naleftClefti,表示剩下的 l e f t left left场中要赢 n − a n-a na场或者更多。
如果下一把A赢,概率就会变成 p 1 = ∑ i = n − a − 1 l e f t − 1 C l e f t − 1 i 2 l e f t − 1 p1=\frac{\sum_{i=n-a-1}^{left-1}{C_{left-1}^{i}}}{2^{left-1}} p1=2left1i=na1left1Cleft1i;

如果下一把A输,概率就会变成 p 2 = ∑ i = n − a l e f t − 1 C l e f t − 1 i 2 l e f t − 1 p2=\frac{\sum_{i=n-a}^{left-1}{C_{left-1}^{i}}}{2^{left-1}} p2=2left1i=naleft1Cleft1i

p 1 、 p 2 p1、p2 p1p2相差 2 ∗ q = C l e f t − 1 n − a − 1 2 l e f t − 1 2*q=\frac{C_{left-1}^{n-a-1}}{2^{left-1}} 2q=2left1Cleft1na1,那么问题就能解决了,空间一定要开够!

AC代码

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,a,n) for(int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
#define int long long 
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
typedef double db;
const int mod=1000000007;
ll powmod(ll a,ll b) {ll res=1;a%=mod;assert(b>=0);for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
// head
const int MAXN=2e5+10;
int n;
int A[MAXN];

void init(){
	A[0]=1;
	rep(i,1,MAXN) A[i]=A[i-1]*i%mod;
}
int inv(int x){
	return powmod(x,mod-2);
}
int C(int a,int b){
	return A[a]*inv(A[b])%mod*inv(A[a-b])%mod;
}

void solve(){
	cin>>n;
	init();
	int tot=powmod(2ll,2*n-1);
	int a=0,b=0;
	rep(i,1,2*n){
		cout<<(2ll*tot%mod*C(2*n-2-a-b,n-a-1)%mod*inv(powmod(2ll,2*n-1-a-b))%mod)%mod<<endl;
		int x;cin>>x;
		a+=(x==0);
		b+=(x==1);
        if(a>=n || b>=n) break;
	}
}

signed main(){
	ios::sync_with_stdio(false);cin.tie(0);cin.tie(0);
	int _=1;
	while(_--) solve();
	return 0;
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值