[Ybt gold medal navigation 1-1-9] guard challenge

Guard challenge

Topic link: ybt gold medal navigation 1-1-9

Topic

There are some tasks, and each task has a certain chance of success.
Success will add a value to a number initially K. (Different tasks will subtract different values, and there will be -1 and positive integers.)
Then you are asked to ensure that the probability of this value being a non-negative number at least L times.

Ideas

The data for this question is small, consider the direct and ordinary dp probability.

Then although KKK can reach2000 20002 0 0 0 , but can be regarded as200 2002 0 0 to see. (Anyway, neither of them will explode the space and affect the result, so that it can also makeKKK becomes200 2002 0 0 ) In other words, at any timeKKK value is greater than200 200At 2 0 0 , you can change it to200 2002 0 0 . (Of course, negative is to−200 -2002 0 0 )
Then we can easily setfi, j, k f_{i,j,k}fi,j,k为前iijjsucceeded in i tasksj , nowKKK value iskkk 的概率。
那得到转移也很容易想到:
{ f i , j , k + a i = f i − 1 , j , k + a i × ( 1.0 − p i ) ( j = 0 ) f i , j , k + a i = f i − 1 , j , k + a i × ( 1.0 − p i ) + f i − 1 , j − 1 , k × p i ( j > 0 ) \left\{\begin{matrix} f_{i,j,k+a_i}=f_{i-1,j,k+a_i}\times (1.0 - p_i)&(j=0)\\ f_{i,j,k+a_i}=f_{i-1,j,k+a_i}\times (1.0 - p_i)+f_{i-1,j-1,k}\times p_i&(j>0) \end{matrix}\right. { fi,j,k+ai=fi1,j,k+ai×(1.0pi)fi,j,k+ai=fi1,j,k+ai×(1.0pi)+fi1,j1,k×pi(j=0)(j>0)
Of course, remember kkThe k value should be equal to200 2002 0 0 takes the minimum value.
And you will findkkThe range of k is− 200 ∼ 200 -200\sim2002002 0 0 , then allkkk plus200 2002 0 0 (all become non-negative before they can be placed in the array), and when the minimum value is reached, it is followed by400 4004 0 0 ratio.

As for initialization, according to the above, kkk plus200 2002 0 0 , it should bef 0, 0, K = 1 f_{0,0,K}=1f0,0,K=1 becomesf 0, 0, K + 200 = 1 f_{0,0,K+200} = 1f0,0,K+200=1 .
(In the beginningkkk isKKK is because ofKK in thebeginningK is this value)

Then after dp is over, let's see how to count the answers.
It is easy to think that we enumerate the number of successful tasks in the last iii , the range isL ∼ n L\sim nLn , thenKKat the end of the enumerationThe value of K jjj , the range is0 ∼ 200 (+ 200) 0\sim200(+200)02 0 0 ( + 2 0 0 ) , then allfn, i, j f_{n,i,j}fn,i,j Adding is the answer we want.

Code

#include<cstdio>
#include<iostream>
#define bp_add 200

using namespace std;

int n, l, K, a[201];
double p[201], f[201][201][402], ans;

int main() {
    
    
	scanf("%d %d %d", &n, &l, &K);
	
	for (int i = 1; i <= n; i++) {
    
    
		scanf("%lf", &p[i]);
		p[i] /= 100.0;
	}
	
	for (int i = 1; i <= n; i++) {
    
    
		scanf("%d", &a[i]);
	}
	
	f[0][0][K + bp_add] = 1.0;
	for (int i = 1; i <= n; i++)
		for (int j = 0; j <= i; j++)
			for (int k = -200; k <= 200; k++) {
    
    
				f[i][j][min(400, k + bp_add + a[i])] = f[i - 1][j][min(400, k + bp_add + a[i])] * (1.0 - p[i]);
				if (j) {
    
    
					f[i][j][min(400, k + bp_add + a[i])] += f[i - 1][j - 1][min(400, k + bp_add)] * p[i];
				}
			}
	
	for (int i = l; i <= n; i++)
		for (int j = bp_add + 0; j <= 200 + bp_add; j++)
			ans += f[n][i][j];
	
	printf("%.6lf", ans);
	
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_43346722/article/details/112688068