题目描述
生成n个∈[a,b]的随机整数,输出它们的和为x的概率。
输入
一行输入四个整数依次为n,a,b,x,用空格分隔。
输出
输出一行包含一个小数位和为x的概率,小数点后保留四位小数
样例输入
2 1 3 4
样例输出
0.3333
1:直接dfs超时;
2:考虑DP求解,n个随机数,如果一次一次拿。可拿n次,每次的数的概率都是1.0÷(b-a+1);
可以定义一个状态dp[i][j],表示前i次的取法和为j的概率,那么它如何从低状态转来?也就是
它和dp[i-1][],前一次的关系式,假如我们知道dp[i-1][]的所有情况,如何推出dp[i][j];即当进行
第i次选择的时候我们有a~b所有的数可选,如果选某个数加起来等于了j就是i-1到i的过程;有
dp[i][j]+=dp[i-1][j-k] (a<=k<=b) 当选择了k(a<=k<=b) 刚好达到状态;
3:dp的初始化在最低的状态;进行第0次选择是概率都是0;进行第1选择是每个数的概率都是
1.0÷(b-a+1);
for(int i=a;i<=b;i++)
dp[1][i]=1.0/(b-a+1);
4:
#include <iostream>
#include <cstdio>
using namespace std;
const int N=105;
int n,a,b,x;
double dp[N][N*N]={0};
int main()
{
cin>>n>>a>>b>>x;
for(int i=a;i<=b;i++)
dp[1][i]=(1.0)/(b-a+1);
for(int i=2;i<=n;i++)
{
for(int j=0;j<=x;j++)
{
for(int k=a;k<=b;k++)
{
if(j>=k)
dp[i][j]+=dp[i-1][j-k]*(1.0)/(b-a+1);
}
}
}
printf("%.4lf",dp[n][x]);
return 0;
}