您的位置:首页 > 其它

poj-1322-Chocolate 使用动态规划求解的一种概率问题的算法

2013-11-12 21:16 489 查看
原题如下:

Chocolate

Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 7931 Accepted: 2078 Special Judge
Description

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种颜色的巧克力放在盒子里,每次可以从中取出一颗放在桌子上,每次取到每种颜色巧克力的概率是相同的(即1/c),如果刚取出的这颗的颜色与桌子上已有的某个巧克力的颜色相同,那么就把这两颗都吃掉,要求解的是取了n次之后桌子上还剩下m颗巧克力的概率是多少。

本题思路如下

第1次取出的时候,因为桌子上此时还没有其它糖果,所以此时只有桌子上剩下1颗这一种可能,概率为1;

第2次取出时,因为桌子上已经有一颗,那么就会有两种情况:

(1)此次取出的与已有的那颗颜色相同,都吃掉,剩下0颗;这种情况发生的概率为1/c

(2)此次取出的与已有的那颗颜色不同,都留在桌子上,剩下两颗;这种情况发生的概率为(c-1)/c

第3次取出时,桌子上的情形有两种可能:

(1)此时桌子上有0颗,那么这次取出的一定可以留在桌子上,即桌子上留下1颗;此种情况发生的概率为条件概率,即(1/c)*1=1/c

(2)此时桌子上有2颗,那么这次取出的就又有两种可能:

1)、此次取出的与已有的两颗中的某一颗颜色相同,那么桌子上就只会留下1颗,概率为【(c-1)/c】*(2/c)

2)、此次取出的与已有的两颗颜色都不同,那么就可以3颗都留在桌子上,概率即为【(c-1)/c】*【(c-2)/c】

。。。。。。

通过对以上较小规模数据情况的分析,基本可以发现每次取出糖果后时桌子上情形可以通过前一次取出时可能发生的情形推算而出,需要的状态表示参数即为当前的次数(设为i)与桌子上剩下的糖果数量(设为j)

那么,以有5种颜色为例,用如下表格来存储各种状态下的概率如下:

 次数 \ 剩余        0              1              2              3         。。。 
01000。。。
10100。。。
21/504/50。。。
3013/25012/25。。。
。。。。。。。。。。。。。。。。。。
(注意用绿色标出的数据不要弄错

由上表可发现:

1、当i与j的奇偶性不同时,概率为0,这是每次因为被吃掉的只能是2颗或0颗;

2、当j>i时,概率皆为0,因为不可能只取了i次,却留下比i更多的糖果;

3、计算该表时发现,对于状态(i,j),其概率可以用(i-1,j-1)和(i-1,j+1)来算出,这是因为既然此次剩余j颗,那么上一次剩余的只可能是j-1颗或j+1颗(结合第1条来理解)

     例如状态(3,1),P(3,1)=P(2,0)*【5-(1-1)】/5+P(2,2)*(2/5)=13/25

     将上式推广即可得出本题的状态转移式:P(i,j)=P(i-1,j-1)* 【(c-(j-1)】/c + P(i-1,j+1)*【(j+1)/c】

得出以上结论后,即可写出本题的解决程序,不过还有一点需要注意:本题要求结果仅需保留3位小数,所以当 i 极大时,因其概率变化会及其微小,不至影响到所需位数,所以可以减小循环次数以节省时间,不过仍需注意刚说的第1条,即奇偶性必须保持

代码如下:

#include<cstdio>
#include<cstring>
double dp[1005][105];
int main()
{
int c,n,m;
while(scanf("%d",&c)&&c)
{
scanf("%d%d",&n,&m);
if(m>n||m>c||(m%2==0&&n%2!=0)||(m%2!=0&&n%2==0))
{
printf("0.000\n");
continue;
}
if(n>1000)
{
if(n%2==0)	n=1000;
else		n=1001;
}
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]=dp[i-1][j-1]*(c-j+1)/c+dp[i-1][j+1]*(j+1)/c;
}
printf("%.3lf\n",dp
[m]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: