Description
1. All of the teams solve at least one problem.
2. The champion (One of those teams that solve the most problems) solves at least a certain number of problems.
Now the organizer has studied out the contest problems, and through the result of preliminary contest, the organizer can estimate the probability that a certain team can successfully solve a certain problem.
Given the number of contest problems M, the number of teams T, and the number of problems N that the organizer expect the champion solve at least. We also assume that team i solves problem j with the probability Pij (1 <= i <= T, 1<= j <= M). Well, can you calculate the probability that all of the teams solve at least one problem, and at the same time the champion team solves at least N problems?
題意:
一場ACM比賽中,有M道題,T只隊伍,現在知道每隻隊伍對於每一題的AC概率,問全場每個隊伍都A出至少一題且至少有一隻隊伍A了N道題的概率。
範圍:
N,M<=30,T<=1000
解法:
畫一個維恩圖: 假設A表示每個隊伍做出至少一題,B表示至少有一隻隊伍做出N題,那麼我們要求解的就是P(A∩B),也就是圖中的黃色部分。
但是直接求至少一個這樣的概率是比較難求的,需要先求反,然後再根據容斥相減得到。
可以考慮先求解P(A∩~B)也就是紅色部分,然後用P(A)-P(A∩~B)得到P(A∩B),其中因爲每一個隊伍是相互獨立的,所以可以單獨求,求解方法爲dp,dp[I][J]表示前I道題做出J道的概率,轉移很簡單,略過(可以看代碼),然後 連乘每一隻隊伍的Σdp[1..N-1]就是P(A∩~B),同理求得P(A),然後相減即可得到P(A∩B)
坑點:POJ加速讀入會跪...POJ的G++不支持%lf輸出,需要用%f...總之就是POJ的judge system 太老了,需要注意一下。
過
代碼:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<iostream>
#include<stdlib.h>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<bitset>
#pragma comment(linker, "/STACK:1024000000,1024000000")
template <class T>
bool scanff(T &ret){ //Faster Input
char c; int sgn; T bit=0.1;
if(c=getchar(),c==EOF) return 0;
while(c!='-'&&c!='.'&&(c<'0'||c>'9')) c=getchar();
sgn=(c=='-')?-1:1;
ret=(c=='-')?0:(c-'0');
while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
if(c==' '||c=='\n'){ ret*=sgn; return 1; }
while(c=getchar(),c>='0'&&c<='9') ret+=(c-'0')*bit,bit/=10;
ret*=sgn;
return 1;
}
#define inf 1073741823
#define llinf 4611686018427387903LL
#define PI acos(-1.0)
#define lth (th<<1)
#define rth (th<<1|1)
#define rep(i,a,b) for(int i=int(a);i<=int(b);i++)
#define drep(i,a,b) for(int i=int(a);i>=int(b);i--)
#define gson(i,root) for(int i=ptx[root];~i;i=ed[i].next)
#define tdata int testnum;scanff(testnum);for(int cas=1;cas<=testnum;cas++)
#define mem(x,val) memset(x,val,sizeof(x))
#define mkp(a,b) make_pair(a,b)
#define findx(x) lower_bound(b+1,b+1+bn,x)-b
#define pb(x) push_back(x)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
double p[1001][33];
double dp[33][33];
int n,t,m;
int main(){
while(scanf("%d%d%d",&m,&t,&n)!=EOF){
if(m==0&&t==0&&n==0)break;
//POJ加速讀入會跪...
rep(i,1,t)
rep(j,1,m)scanf("%lf",&p[i][j]);
double pa=1.0;
double pb=1.0;
rep(k,1,t){
dp[0][0]=1;
rep(i,1,m)
rep(j,0,i){
dp[i][j]=dp[i-1][j]*(1.0-p[k][i]);
if(j)dp[i][j]+=dp[i-1][j-1]*p[k][i];
}
double suma,sumb;
suma=sumb=0;
rep(i,1,n-1)sumb+=dp[m][i],suma+=dp[m][i];
rep(i,n,m)suma+=dp[m][i];
pa*=suma;
pb*=sumb;
}
//POJ的G++不支持%lf輸出...
printf("%.3f\n",pa-pb);
}
}<strong>
</strong>