求解投骰子游戏问题

[问题描述] 玩家根据骰子的点数决定走的步数,即骰子点数为1时可以走一步,点数为2时可以走两步,点数为n时可以走n步。求玩家走到第n步(n <= 骰子最大点数且投骰子方法唯一)时总共有多少种投骰子的方法数.

[输入描述] 输入包含一个整数n(1 <= n <= 6)

[输出描述] 输出一个整数,表示投骰子的方法数。

[输入样例] 6

[样例输出] 32

[思路] 设f(n)表示玩家走到第n步时投骰子的方法数。显然:

n = 1时,只有投骰子点数为1的一种情况。即f(1) = 1.

n = 2时,只有两次投骰子点数为1和一次投骰子点数为2的两种情况。即f(2) = 2

对于n,第一次投骰子点数为1,剩余n-1步,此时f(n) = f(n-1);第一次投骰子点数为2,剩余n-2步,此时f(n)=f(n-2);…第一次投骰子点数为n,只有一种情况,此时f(n)=1.所以有f(n)=f(n-1)+f(n-2)+f(n-3)+…+f(1)+1

对应的递归模型如下:
f ( n ) = { 1 , 当 n = 1 时 2 , 当 n = 2 时 f ( n − 1 ) + f ( n − 2 ) + . . . . f ( 1 ) + 1 , 当 n > 2 时 f(n)=\begin{cases} 1,当n=1时\\ 2,当n=2时\\ f(n-1)+f(n-2)+....f(1)+1,当n>2时 \end{cases} f(n)=1,n=12,n=2f(n1)+f(n2)+....f(1)+1,n>2
可以采用以下递归算法求解:

long f(int n)
{
    if(n == 1)
    {
        return 1;
    }
    if(n == 2)
    {
        return 2;
    }
    long sum = 1;
    for(int i = 1;i <= n - 1;i++)
    {
        sum += f(i);
    }
}

一个更优的方法是采用非递归方法。看看前面递归模型的递推过程,可以总结出如下的递推关系。

f(1) = 1
f(2) = 2
f(3) = f(2) + f(1) + 1 = (2 + 1) + 1 = 2的平方 - 1 + 1 = 2的平方
f(4) = f(3) + f(2) + f(1) + 1 = (2的平方 + 2 + 1) + 1 = 2的3次方 - 1 + 1 = 2的3次方
f(5) = f(4) + f(3) + f(2) + f(1) + 1 = (2的三次方 + 2的平方 + 2 + 1) + 1 = 2的四次方 - 1 + 1 = 2的4次方

依次类推,可以得到f(n) = 2n-1 .对应的完整程序如下:

[完整程序]

#include <iostream>
using namespace std;
int main()
{
    int n;
    cin >> n;
    cout << (long)pow(2,n-1) << endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吃掉你的脑子·

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值