51nod 1667 概率好题
2016-11-03 20:57
281 查看
Problem
甲乙进行比赛。他们各有k1,k2个集合[Li,Ri]
每次随机从他们拥有的每个集合中都取出一个数
S1=∑甲取出的数
S2同理
若S1>S2甲胜 若S1=S2平局 否则乙胜
分别求出甲胜、平局、乙胜的概率。
Solution
对于甲的每个数可以表示为这样一个形式Ri−xi其中xi∈[0,Ri−Li]类似的,对于乙中的每个数可以表示为这样一个形式Li+yi其中yi∈[0,Ri−Li]
那么甲胜利的条件即为:
∑Ri−∑xi>∑Li+∑yi
变形为:
∑xi+∑yi<∑Ri−∑Li
于是可以发现右边的是一个常数
我们加入一个变量k(k∈[0,+∞)
那么不等式变成:
∑xi+∑yi+k=∑Ri−∑Li−1
(注意有一个-1是因为不等式中是<)
于是就变成了求方程有多少个不同的解。
容斥
问题现在变成:我们有一个有k1+k2+1个未知数的方程,其中每个未知数都是非负整数且有上限,现在我们需要知道有多少组解。
于是我们可以容斥,答案要求的是满足所有未知数都在其上限以内的方案数,于是设S(i)表示至少有i个未知数不符合要求的方案数,那么可以得到:
Ans=∑(−1)i×S(i)
枚举未知数符合或不符合的状态,那么对于一个不符合要求的未知数,由于原本应当是xi≤upi,不符合就变成xi>upi,即xi−upi−1≥0
所以将等式的常数减去upi+1就变成了经典的挡板问题:将n个球放进m个盒子里,求方案数。(注意:由于此问题中m很小,于是可以直接暴力算组合数)
记第一道640
Code
#include<iostream> #include<algorithm> #include<cstdio> #include<cmath> #include<cstring> #define fo(i,a,b) for(int i=a;i<=b;i++) #define fd(i,a,b) for(int i=a;i>=b;i--) using namespace std; int get(){ char ch; int s=0; bool bz=0; while(ch=getchar(),(ch<'0'||ch>'9')&&ch!='-'); if (ch=='-')bz=1;else s=ch-'0'; while(ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-'0'; if (bz)return -s; return s; } const int N = 20; const int mo = 1e+9+7; typedef long long LL; int u ; int n,k1,k2,t; LL sum,ans; bool bz ; LL quickmi(LL x,LL tim){ LL ans=1; while(tim){ if (tim%2)ans=ans*x%mo; x=x*x%mo; tim/=2; } return ans; } LL c(LL n,int m){ LL ans=1; fo(i,1,m)ans=ans*(n-i+1)%mo; fo(i,1,m)ans=ans*quickmi(i,mo-2)%mo; return ans; } void calc(){ LL tmp=sum; fo(i,1,n) if (bz[i])tmp-=u[i]+1; if (tmp<0)return; LL v=c(tmp+n,n); bool pd=0; fo(i,1,n)pd^=bz[i]; if (pd)ans=(ans+mo-v)%mo; else ans=(ans+v)%mo; } void getans(int x){ if (x>n){ calc(); return; } bz[x]=0; getans(x+1); bz[x]=1; getans(x+1); } int main(){ t=get(); fo(cas,1,t){ k1=get(); sum=0; fo(i,1,k1){ int l=get(),r=get(); u[i]=r-l; sum+=r; } k2=get(); fo(i,1,k2){ int l=get(),r=get(); u[i+k1]=r-l; sum-=l; } n=k1+k2; u[n+1]=1e+9; sum--; LL ans1=0;ans=0; if(sum<0)ans1=0; else{ getans(1); ans1=ans; } ans=0; sum++; if (sum<0)ans=0; else getans(1); ans=(ans-ans1+mo)%mo; fo(i,1,n)ans=ans*quickmi(u[i]+1,mo-2)%mo; fo(i,1,n)ans1=ans1*quickmi(u[i]+1,mo-2)%mo; printf("%lld %lld %lld\n",ans1,ans,(1+mo*2-ans-ans1)%mo); } return 0; }
相关文章推荐
- 51nod 1667 概率好题 组合数学+容斥原理
- [51nod 1667]概率好题
- 51nod 1667 概率好题
- [51nod 1667]概率好题
- [51nod 1667]概率好题
- 51nod 1667 概率好题 组合数学+容斥原理
- 51nod 1398 等公交【概率DP】
- 51Nod-算法马拉松23 B 谷歌的恐龙 [概率期望]【数学】
- 杭二集训 disanti (51Nod 1667 概率好题)
- 51Nod 1381 硬币游戏 | 概率(数学期望)
- 51NOD 1836 战忽局的手段(矩阵乘法加速+__float128精度问题+概率期望)——算法马拉松20(告别美国大选及卡斯特罗)
- 【概率DP】51Nod 1398 等公交
- 多核编程中的任务随机竞争模式的概率分析
- POJ-1322 Chocolate(概率DP)
- 51Nod 1417 天堂里的游戏
- 【51nod】1461 稳定桌 扫描线+线段树
- 古典概型、几何概型与概率的区别与联系
- 51Nod 1001 数组中和等于K的数对
- 【BZOJ 4318】[概率DP]OSU!
- 51nod-1082与七无关的数