One question per day of the competition dfs dp

Topic: https://ac.nowcoder.com/acm/problem/14734
You are playing a game, there are a total of 12 problems in this game

For the i-th problem, your team has a[i] chance to solve her

What if she can't be solved?

Because everyone discusses very loudly

So you have the probability of b[i] to listen to this question from the team on the left

Probability of c[i] listen to this question from the team on the right

What is the probability that your team will solve 0-12 problems in the end?

Input description:
12 numbers in the first line represent a[1] -> a[12]
12 numbers in the second line represent b[1] -> b[12]
12 numbers in the third line represent c[1] -> c[12]

Output description:
output 13 lines, the i-th line represents the probability of solving i-1 problem,
6 decimal places

Example 1

Input
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

Output
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

There are two approaches to this topic, the first dfs. Because the range of question data is small, the number of questions is only 12. Each problem is either done or cannot be done in two states. The largest is 2^12. Direct brute force search is possible.
First of all, it is difficult to reverse, it is easy to get the probability that each problem can not be done, (1-a[i]) (1-b[i]) (1-c[i]), then you can get the probability of doing it It is 1-(1-a[i]) (1-b[i]) (1-c[i]). r is the current value of the right. When the number of the right is less than the requirement, you can search both sides. Otherwise, you can only search in directions you can't do.
Code:

#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;
}

The second method: dp method, use dp[i][j] to represent the probability that the first i matches j. Then the probability of dp[i][j] is equal to the probability that the first i-1 is correct for j, which is incorrect, plus the probability that the first i-1 is correct for j-1, and this is correct. dp[i][j]=dp[i-1][j]*(1-p[i])+dp[i-1][j-1] p[i].
When j=0, j-1<0, then make a special judgment, its probability is equal to dp[i-1][0]
(1-p[i]).
Code:

#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;
}
`

Guess you like

Origin blog.csdn.net/u011612364/article/details/108553360