Probability Memory Search of Nested Function

Nested functions (use step by step to solve problems)

Title description

Consider the function: randomInt(N). The function returns an integer from 0 to N-1 randomly and uniformly. If the function is nested, such as randomInt(randomInt(N)), the probability distribution will change, and some numbers are more likely to change than others.

Now give N, then give the nesting level times, and ask what is the probability of getting the integer Y.

Input format

Multiple sets of test data.

In the first line, an integer G indicates that there are G groups of test data. 1 <= G <= 10

Each test data format:

 In the first line, three integers: N, times, Y. 1 <= N <= 1000, 1<=times<=10, 0<=Y<=N-times.

Output format

A total of G lines, a total of G lines, each line has a real number, the error does not exceed 0.0001.

Input sample

10
5 2 1
10 4 0
1000 10 990
1000 7 0
1 1 0
50 4 0
10 10 0
1000 10 1
752 6 0
886 2 170

Sample output

0.21666666666666667
0.19942680776014104
1.0461776397050886E-30
0.165676656915066
1.0
0.23479574692949326
2.7557319223985894E-7
0.03398906538272463
0.1606392598541192
0.001859385756588236

Problem solving ideas

The main idea: What is the probability of getting Y in this random function with nested times layer.

By drawing a picture of the situation in this question, we can get a tree diagram similar to that of a knight , so this question is solved by using dfs.

d f s ( t , n u m b e r ) dfs(t,number) dfs(t,n u m b e r ) means that the current function still hasttAt level t , the current function value is 0-(number-1), and the probability that the function gets Y.

In this level of function, it is possible to get any number between 0-(number-1), so we need to enumerate the number between 0-(number-1), and then enter the next level of recursion.

When you find that Y is not between 0 and (number-1), you should directly exit this layer of recursion (return 0;). When all functions are calculated and Y is obtained, 1 is to be returned.

This question is the same as that of the knight, which requires memory search.


Code

#include<bits/stdc++.h>

using namespace std;
int G,times,Y,N;
double rec[15][1005];
bool vis[15][1005];

double dfs(int i,int num)
{
    
    
	if(i==0)//函数算完
	{
    
    
		if(num==Y) return 1.0;//且算到Y
		else return 0.0;
	}
	if(num-1<Y) return 0.0;//Y不在随机区间内
	if(vis[i][num]==1) return rec[i][num];//记忆化
	for(int k=0;k<num;k++)
		rec[i][num]+=(1.00/double(num))*dfs(i-1,k);//概率计算
	vis[i][num]=1;
	return rec[i][num];
}

int main()
{
    
    
	freopen("2800.in","r",stdin);
	freopen("2800.out","w",stdout);
	cin>>G;
	for(int gr=1;gr<=G;gr++)
	{
    
    
		cin>>N>>times>>Y;
		memset(vis,0,sizeof(vis));
		memset(rec,0.0,sizeof(rec));
		cout<<fixed<<setprecision(6)<<dfs(times,N)<<endl;
	}
	return 0;
}

Guess you like

Origin blog.csdn.net/bell041030/article/details/89052089