Chocolate (POJ-1322)(概率DP)

In 2100, ACM chocolate will be one of the favorite foods in the world.

"Green, orange, brown, red...", colorful sugar-coated shell maybe is the most attractive feature of ACM chocolate. How many colors have you ever seen? Nowadays, it's said that the ACM chooses from a palette of twenty-four colors to paint their delicious candy bits.

One day, Sandy played a game on a big package of ACM chocolates which contains five colors (green, orange, brown, red and yellow). Each time he took one chocolate from the package and placed it on the table. If there were two chocolates of the same color on the table, he ate both of them. He found a quite interesting thing that in most of the time there were always 2 or 3 chocolates on the table.

Now, here comes the problem, if there are C colors of ACM chocolates in the package (colors are distributed evenly), after N chocolates are taken from the package, what's the probability that there is exactly M chocolates on the table? Would you please write a program to figure it out?

Input

The input file for this problem contains several test cases, one per line.

For each case, there are three non-negative integers: C (C <= 100), N and M (N, M <= 1000000).

The input is terminated by a line containing a single zero.

Output

The output should be one real number per line, shows the probability for each case, round to three decimal places.

Sample Input

5 100 2

0

Sample Output

0.625 

題意:袋中有C種顏色巧克力,每次從其中拿出一塊放桌上,如果桌上有兩塊相同顏色巧克力則吃掉,問取出N塊巧克力後,求桌上正好剩下M塊巧克力的概率。(已知,若有五種顏色,會發現大部分時間桌上有2或3塊巧克力。)

思路:這道題的話,因爲讓你求概率,所以我們優先考慮概率DP的做法。首先,我們考慮如果取出來的巧克力與桌面上原有的m+1個巧克力中的一個巧克力顏色相同,此時可以取走這個巧克力來實現(n-1,m+1)—>(n,m)的轉化,概率爲(m+1)/c。其次,我們取出來的巧克力與桌面上原有的m-1個巧克力都不同色,此時我們可以將取出來的巧克力放在桌面上來實現(n-1,m-1)—>(n,m)的轉化,概率爲1-(m-1)/c。然後我們設dp[i][j]爲取了i個還剩j個的概率。由此可得遞推方程爲:dp[i][j]=(j+1)*dp[i-1][j+1]/(c*1.0)+(c-j+1)*dp[i-1][j-1]/(c*1.0)。

AC代碼:

#include <stdio.h>
#include <string>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <queue>
#include <stack>
#include <map>
#include <set>
typedef long long ll;
const int maxx=1010;
const int mod=10007;
const int inf=0x3f3f3f3f;
const double eps=1e-5;
using namespace std;
double dp[maxx][maxx];
int main()
{
    int c,n,m;
    while(~scanf("%d",&c),c)
    {
        scanf("%d%d",&n,&m);
        if(m>c || m>n || (n+m)%2!=0)
        {
            printf("0.000\n");
            continue;
        }
        if(n>1000)
            n=1000+n%2;
        memset(dp,0,sizeof(dp));
        dp[0][0]=1;
        for(int i=1; i<=n; i++)
        {
            dp[i][0]=dp[i-1][1]/c;
            dp[i][c]=dp[i-1][c-1]/c;
            for(int j=1; j<c; j++)
            {
                dp[i][j]=(j+1)*dp[i-1][j+1]/(c*1.0)+(c-j+1)*dp[i-1][j-1]/(c*1.0);
            }
        }
        printf("%.3lf\n",dp[n][m]);
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章