zoukankan      html  css  js  c++  java
  • 【POJ】2151 Check the difficulty of problems

    http://poj.org/problem?id=2151

    题意:T个队伍M条题目,给出每个队伍i的每题能ac的概率p[i][j],求所有队伍至少A掉1题且冠军至少A掉N题的概率(T<=1000, M<=30)

    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int T=1005, M=35;
    double d[T][M], p[T][M];
    int n, m, N;
    void clr() {
    	for(int i=1; i<=n; ++i) for(int j=1; j<=m; ++j) d[i][j]=0;
    }
    int main() {
    	while(scanf("%d%d%d", &m, &n, &N), !(m==0&&n==0&&N==0)) {
    		for(int i=1; i<=n; ++i) for(int j=1; j<=m; ++j) scanf("%lf", &p[i][j]);
    		for(int i=1; i<=n; ++i) d[i][0]=1;
    		for(int i=1; i<=n; ++i) 
    			for(int k=1; k<=m; d[i][0]*=1-p[i][k], ++k) 
    				for(int j=m; j; --j) d[i][j]=d[i][j]*(1-p[i][k])+d[i][j-1]*p[i][k];
    		//for(int i=1; i<=n; ++i) { for(int j=0; j<=m; ++j) printf("%.2f ", d[i][j]); puts(""); }
    		for(int i=1; i<=n; ++i) for(int j=m; j; --j) d[i][j]+=d[i][j+1];
    		double ans=0, sum;
    		for(int i=1; i<=n; ++i) {
    			sum=d[i][N];
    			for(int j=1; j<i; ++j) sum*=(d[j][1]-d[j][N]);
    			for(int j=i+1; j<=n; ++j) sum*=d[j][1];
    			ans+=sum;
    		}
    		printf("%.3f
    ", ans);
    		clr();
    	}
    	return 0;
    }
    

      

    我们只需要设状态就行了= =随便搞...

    设f[i][j][k]表示第i队解决j~k个问题的概率

    $$ans=sum_{i} left( f[i][N][M] * prod_{j<i} f[j][1][N-1] * prod_{j>i} f[j][1][M] ight) $$

    这样就能不重不漏....(不难理解,我觉得这个很简单的吧= =

    然后我们来一发前缀和,d[i][j]表示第i队解决至少j个问题的概率

    $$ans=sum_{i} left( d[i][N] * prod_{j<i} ( d[j][1]-d[j][N] ) * prod_{j>i} d[j][1] ight) $$

    问题转化为如何求d[i][j]...

    设d'[i][j]表示第i队解决j个问题的概率

    我们类似背包依次加入每个问题,有

    d[i][j]=d[i][j]*(1-p[i][k])+d[i][j-1]*p[i][k](自己好好思考= =,我拐了好多个弯才想出来QAQ

    于是就ok了。。。

  • 相关阅读:
    期权标的概率密度函数
    Girsanov Theorem
    拉马努金恒等式
    波动率的三类模型
    stack(栈) and heap(堆)
    covar of lognormal variables
    BS 相关的一些近似公式
    布朗运动的一些特殊性质
    排序算法
    Mac node.js
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/4297768.html
Copyright © 2011-2022 走看看