DP2 概率DP

it2025-04-18  5

题目描述 生成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; }
最新回复(0)