標籤:dp
問題描述
產生n個∈[a,b]的隨機整數,輸出它們的和為x的機率。
輸入格式
一行輸入四個整數依次為n,a,b,x,用空格分隔。
輸出格式
輸出一行包含一個小數位和為x的機率,小數點後保留四位小數
範例輸入
2 1 3 4
範例輸出
0.3333
資料規模和約定
對於50%的資料,n≤5.
對於100%的資料,n≤100,b≤100.
題解:
這是一道典型的完全背包,但是在做的過程中遇到了一些波折。
dp[i][j]:挑選i個數字後得到j的機率。
dp[i][j]=dp[i-1][z]*1/sum;
每一種情況都要再乘一個1/sum,而情況與情況之間是加和的關係。
(最開始想用得到X數/總數),後來發現到最後實在太大了,100^100.所以用dp直接表示機率更好一點,剩下的就是一個完全背包了。
代碼實現:
#include <bits/stdc++.h>#define MAX 110using namespace std;double dp[MAX][MAX*MAX];int save[MAX];double sum;int N,a,b,X;int main(){ scanf("%d%d%d%d",&N,&a,&b,&X); for( int i = 0; i < b-a+1; i++ ) save[i]=a+i; sum = b-a+1; memset(dp,0,sizeof(dp)); for( int i = 0; i < N; i++ ) { for( int j = 0; j < b-a+1; j++ ) { if( i == 0 ) { dp[i][save[j]]=1/sum; smax=max(smax,save[j]); } else { int smax=0; int tem=0; for( int z = 0; z < MAX*MAX-save[j]; z++ ) { if( dp[i-1][z] != 0 ) { dp[i][z+save[j]]+=(dp[i-1][z]*1/sum); tem=max(smax,z+save[j]); } if( z > smax ) { smax=tem; break; } } } } } printf("%.4lf\n",dp[N-1][X]);}
機率統計(DP)