poj 1322 Chocolate

本文解析了一道经典的概率DP题目(POJ 1322),介绍了如何通过动态规划的方法解决从多种颜色的巧克力中抽取特定数量后剩余指定数量的问题。文中详细解释了状态转移方程,并提供了完整的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 题目:http://poj.org/problem?id=1322

 题意:有C种不同颜色的巧克力,每种巧克力同样多,把巧克力一个一个拿到桌子上,当发现有相同颜色就把相同颜色的吃掉,求取出n个后,还剩m个在桌子上的概率。

 

 刚开始被题目的数据范围吓住了,知道用dp,但不敢下手,看了discuss,尼玛把大于1000的奇数改为1001,偶数改为1000就行了,不知道为什么是对的,试着敲了下,居然过了~~~

 很显然,当某时刻桌子上还剩m个巧克力,它们的颜色一定都不相同。用dp[i][j]表示取i个巧克力后,还剩j个的概率。则对每个dp[i][j],如果新拿出的巧克力与目前桌子上的巧克力颜色都不相同,则概率为(c-j+1)/c,若新拿出的巧克力与目前桌子上的某个巧克力颜色相同,则概率为(j+1)/c(原来桌上有j+1个,拿出来一个,吃了两个,最后剩下j个),于是dp[i][j]=dp[i-1][j-1]*(c-j+1)/c+dp[i-1][j+1]*(j+1)/c。

 

#include<cstdio>
#include<cstring>
double dp[1005][1005];
int main()
{
   int c,n,m,i,j;
   while(scanf("%d",&c),c)
   {
      scanf("%d%d",&n,&m);
	  if(m>c||m>n||(n+m)%2==1)
	  {
	     printf("0.000\n");
		 continue;
	  }
	  if(n>1000)
		  n=1000+n%2;
	  memset(dp,0,sizeof(dp));
	  dp[0][0]=1;
	  for(i=1;i<=n;i++)
		for(j=0;j<=c;j++)
		{
		   if(j==0)
			   dp[i][j]=dp[i-1][j+1]/c;
		   else if(j==c)
			   dp[i][j]=dp[i-1][j-1]/c;
		   else
			   dp[i][j]=dp[i-1][j-1]*(c-j+1)/c+dp[i-1][j+1]*(j+1)/c;

		}
	  printf("%.3lf\n",dp[n][m]);
   }
   return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值