60:n个骰子的点数

递归:

int getNsumCount(int n, int sum)
{
    if (n < 1 || sum < n || sum>6 * n)return 0;
    if (n == 1)return 1;
    int resCount = 0;
    resCount = getNsumCount(n - 1, sum - 1) + getNsumCount(n - 1, sum - 2) + getNsumCount(n - 1, sum - 3) +
        getNsumCount(n - 1, sum - 4) + getNsumCount(n - 1, sum - 5) + getNsumCount(n - 1, sum - 6);
    return resCount;
}

动态规划

1.现在变量有:骰子个数,点数和。当有k个骰子,点数和为n时,出现次数记为f(k,n)。那与k-1个骰子阶段之间的关系是怎样的?

2.当有k-1个骰子时,再增加一个骰子,这个骰子的点数只可能为1、2、3、4、5或6。那k个骰子得到点数和为n的情况有:

(k-1,n-1):第k个骰子投了点数1

(k-1,n-2):第k个骰子投了点数2

(k-1,n-3):第k个骰子投了点数3

....

(k-1,n-6):第k个骰子投了点数6

在k-1个骰子的基础上,再增加一个骰子出现点数和为n的结果只有这6种情况!
所以:f(k,n)=f(k-1,n-1)+f(k-1,n-2)+f(k-1,n-3)+f(k-1,n-4)+f(k-1,n-5)+f(k-1,n-6)
3.有1个骰子,f(1,1)=f(1,2)=f(1,3)=f(1,4)=f(1,5)=f(1,6)=1。
递归函数,返回和为n出现的次数。所有的和出现次数总和为6^n。

https://blog.csdn.net/k346k346/article/details/50988681

int getNsumCountnotRecusion(int n, int *count)
{
    if (n < 1)return -1;
    count[0] = count[1] = count[2] = count[3] = count[4] = count[5] = 1;
    for (int i = 2; i <= n; i++)
    {
        for (int sum = 6 * i; sum >= i; sum--)
        {
            int tmp1 = ((sum - 1 - (i - 1)) >= 0 ? count[sum - 1 - (i - 1)] : 0);//两个骰子不可能存在和为2的情况
            int tmp2 = ((sum - 2 - (i - 1)) >= 0 ? count[sum - 2 - (i - 1)] : 0);//三个骰子不可能存在和为3的情况
            int tmp3 = ((sum - 3 - (i - 1)) >= 0 ? count[sum - 3 - (i - 1)] : 0);//因此都减去了i-1
            int tmp4 = ((sum - 4 - (i - 1)) >= 0 ? count[sum - 4 - (i - 1)] : 0);
            int tmp5 = ((sum - 5 - (i - 1)) >= 0 ? count[sum - 5 - (i - 1)] : 0);
            int tmp6 = ((sum - 6 - (i - 1)) >= 0 ? count[sum - 5 - (i - 1)] : 0);
            count[sum - i] = tmp1 + tmp2 + tmp3 + tmp4 + tmp5 + tmp6;
        }
    }
    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。