比赛 每日一题 dfs dp

题目:https://ac.nowcoder.com/acm/problem/14734
你在打比赛,这场比赛总共有12个题

对于第i个题,你的队伍有a[i]的几率解决她

如果解决不了她呢?

由于所有人讨论的都很大声

所以你有b[i]的概率从左边那个队那里听会这个题的做法

有c[i]的概率从右边那个队那里听会这个题的做法

请问最终你们队伍解出0-12题的概率分别是多少

输入描述:
第一行12个数表示a[1] -> a[12]
第二行12个数表示b[1] -> b[12]
第三行12个数表示c[1] -> c[12]

输出描述:
输出13行,第i行表示解出i-1题的概率
保留6位小数

示例1

输入
0.20 0.30 0.37 0.40 0.45 0.50 0.57 0.60 0.75 0.76 0.77 0.83
0.85 0.88 0.90 0.94 0.100 0.104 0.105 0.107 0.115 0.120 0.122 0.125
0.128 0.130 0.134 0.140 0.149 0.150 0.152 0.155 0.170 0.183 0.203 0.240

输出
0.000000
0.000000
0.000000
0.000011
0.000160
0.001508
0.009620
0.041938
0.124153
0.243773
0.301960
0.212453
0.064424

这个题目有两种做法,第一种的dfs。因为题目数据范围较小,题目数量只有12。每道题目要么做出来要么做不出来来两种状态。最大也就是2^12.可以直接暴力搜索。
首先正难则反,容易得到每个题目做不出来的概率,(1-a[i])(1-b[i])(1-c[i]),那么就可以得到做出来的概率是1-(1-a[i])(1-b[i])(1-c[i])。r为当前做对的值,当做对的数量小于要求时,可以往做出和做不出两边搜索。否则只能往做不出的方向搜索。
代码:

#include <bits/stdc++.h>
#include <algorithm>
#include<iostream>
#include <stdio.h>
#define INF 0x3f3f3f3f
//const int maxn=;
using namespace std;
typedef long long ll;
double a[15],b[15],c[15],p[15];
double answer=0.0;
void dfs(int need,int pos,int r,double ans){
    
    
    if(pos==13){
    
    
       if(r==need)
            answer+=ans;
        return;
    }
    if(r<need){
    
    
        dfs(need,pos+1,r+1,ans*p[pos]);
    }
    dfs(need,pos+1,r,ans*(1-p[pos]));
}
int main (){
    
    
    for(int i=1;i<=12;i++)
        cin>>a[i];
    for(int i=1;i<=12;i++)
        cin>>b[i];
    for(int i=1;i<=12;i++)
        cin>>c[i];
    //int cnt=0;
    for(int i=1;i<=12;i++){
    
    
        p[i]=1-(1-a[i])*(1-b[i])*(1-c[i]);
    }
    //cout<<cnt<<endl;
    for(int i=1;i<=13;i++){
    
    
        answer=0.0;
        dfs(i-1,1,0,1);
        printf("%.6lf\n",answer);
    }
    return 0;
}

第二种:dp做法,用dp[i][j]表示前i个对了j个的概率。那么dp[i][j]的概率就等于前i-1个对了j个的,这个不对的概率,加上前i-1个对了j-1个,这个对了的概率。dp[i][j]=dp[i-1][j]*(1-p[i])+dp[i-1][j-1]p[i]。
j=0的时候,j-1<0,那么就特殊判断一下,它的概率等于dp[i-1][0]
(1-p[i])。
代码:

#include <bits/stdc++.h>
#include <algorithm>
#include<iostream>
#include <stdio.h>
#define INF 0x3f3f3f3f
//const int maxn=;
using namespace std;
typedef long long ll;
double a[15],b[15],c[15],p[15];
double dp[15][15];

int main (){
    
    
    for(int i=1;i<=12;i++)
        cin>>a[i];
    for(int i=1;i<=12;i++)
        cin>>b[i];
    for(int i=1;i<=12;i++)
        cin>>c[i];
    //int cnt=0;
    for(int i=1;i<=12;i++){
    
    
        p[i]=1-(1-a[i])*(1-b[i])*(1-c[i]);
    }
    //cout<<cnt<<endl;
    dp[0][0]=1;
    // dp[1][0]=1-p[1];
    // dp[1][1]=p[1];
    // for(int i=2;i<=12;i++)
    //     dp[i][0]=dp[i-1][0]*(1-p[i]);
    for(int i=1;i<=12;i++){
    
    
        for(int j=0;j<=i;j++){
    
    
            //double ans=dp[i-1][j]*(1-p[i]+dp[i-1][j-1]*p[i]);
            if(j!=0)
                dp[i][j]=dp[i-1][j]*(1-p[i])+dp[i-1][j-1]*p[i];
            else
                dp[i][0]=dp[i-1][0]*(1-p[i]);
        }
    }
    for(int i=0;i<=12;i++)
        printf("%.6lf\n",dp[12][i]);
    return 0;
}
`

猜你喜欢

转载自blog.csdn.net/u011612364/article/details/108553360