问题的解等于(所有队都做出至少一题的概率 - 所有队做题数都在1到N-1之间的概率)
设计DP状态时,因为DP过程中要记录哪些题做过了很难,一般来说要把DP的过程设计成有方向的,比如有一维表示前i个XX这种。
dp[i][j][k]表示第i队前j题做出k个的概率,dp方程就是dp[i][j][k]=dp[i][j-1][k-1]*acr[i][j]+dp[i][j-1][k]*(1-acr[i][j])
初始化dp[i][0][0]为1,dp[i][j][0]都设为相应情况所有题全错的概率。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define LL long long
double dp[1005][35][35];
double acr[1005][35];
int M,T,N;
int main(){
while(~scanf("%d%d%d",&M,&T,&N)){
if(!M&&!T&&!N) break;
for(int i=0;i<T;i++){
for(int j=1;j<=M;j++){
scanf("%lf",&acr[i][j]);
}
}
for(int i=0;i<T;i++){
dp[i][0][0]=1;
for(int j=1;j<=M;j++){
dp[i][j][0]=dp[i][j-1][0]*(1-acr[i][j]);
}
}
for(int i=0;i<T;i++){
for(int j=1;j<=M;j++){
for(int k=1;k<=j;k++){
dp[i][j][k]=dp[i][j-1][k-1]*acr[i][j]+dp[i][j-1][k]*(1-acr[i][j]);
}
}
}
double tot=1;
double sub=1;
for(int i=0;i<T;i++){
double cur=0;
for(int j=1;j<=M;j++){
cur+=dp[i][M][j];
}
tot*=cur;
cur=0;
for(int j=1;j<N;j++){
cur+=dp[i][M][j];
}
sub*=cur;
}
printf("%.3f\n",tot-sub);
}
return 0;
}
本文介绍了一种使用动态规划(DP)解决比赛中各队伍完成题目数量概率问题的方法。通过定义dp[i][j][k]表示第i队前j题做出k个的概率,并给出相应的DP方程,最终计算出所有队都至少完成一题的概率减去所有队完成题目数量都在1到N-1之间的概率。
304

被折叠的 条评论
为什么被折叠?



