巧克力问题:
有袋子里均匀地装着 c
种颜色的巧克力,每种巧克力均有无限多。每次从袋子里拿一块
放在桌子上,如果桌子上已经有一块颜色相同的巧克力,就把两块巧克力都吃掉。一共
取出了
n
块巧克力,问:最后桌子上有
m
块的概率为多大。例如
c=5,n=100,m=2
时,概
率为
0.625
。
#include<iostream>
using namespace std;
double c; //c种颜色
double dp[10000][10000]; //用于保存之前算出来的结果,避免重复计算
double dp_vis[10000][10000]; //因为dp矩阵存储的是概率,可能为0,0的话不好当做判断语句。所以多用一个二维矩阵来作为判断条件
double probability(int n, int m) {
if (dp_vis[n][m] != 0 || n == 1 || n == 2)
return dp[n][m];
else {
double a = probability(n - 1, m - 1) * (c - m + 1) / c;
double b = probability(n - 1, m + 1) * (m + 1) / c;
dp[n][m] = a + b;
dp_vis[n][m] = 1;
return dp[n][m];
}
}
int main() {
c = 5;
memset(dp, 0, sizeof(dp));
memset(dp_vis, 0, sizeof(dp_vis));
dp[1][0] = 0;
dp[1][1] = 1;
dp[2][2] = 0.5;
dp[2][0] = 0.5;
dp_vis[1][0] = dp_vis[1][1] = dp_vis[2][2] = dp_vis[2][0] = 1;
double ans = probability(100, 2);
cout << ans;
return 0;
}
用斐波那契类似的递归+动态规划去掉重复计算