P1057 传球游戏(递推/DP?)

本文介绍了一个有趣的传球游戏问题,探讨了如何通过算法计算特定条件下传球返回起点的方法数量。使用了动态规划方法,针对不同的人数和传球次数进行计算。

题目描述

上体育课的时候,小蛮的老师经常带着同学们一起做游戏。这次,老师带着同学们一起做传球游戏。

游戏规则是这样的: nnn 个同学站成一个圆圈,其中的一个同学手里拿着一个球,当老师吹哨子时开始传球,每个同学可以把球传给自己左右的两个同学中的一个(左右任意),当老师再次吹哨子时,传球停止,此时,拿着球没有传出去的那个同学就是败者,要给大家表演一个节目。

聪明的小蛮提出一个有趣的问题:有多少种不同的传球方法可以使得从小蛮手里开始传的球,传了 mmm 次以后,又回到小蛮手里。两种传球方法被视作不同的方法,当且仅当这两种方法中,接到球的同学按接球顺序组成的序列是不同的。比如有三个同学 111 号、 222 号、 333 号,并假设小蛮为 111 号,球传了 333 次回到小蛮手里的方式有 111 -> 222 -> 333 -> 111 和 111 -> 333 -> 222 -> 111 ,共 222 种。

输入输出格式

输入格式:

 

一行,有两个用空格隔开的整数 n,m(3≤n≤30,1≤m≤30)n,m(3 \le n \le 30,1 \le m \le 30)n,m(3≤n≤30,1≤m≤30) 。

 

输出格式:

 

111 个整数,表示符合题意的方法数。

 

输入输出样例

输入样例#1: 复制

3 3

输出样例#1: 复制

2

说明

40%的数据满足: 3≤n≤30,1≤m≤203 \le n \le 30,1 \le m \le 203≤n≤30,1≤m≤20

100%的数据满足: 3≤n≤30,1≤m≤303 \le n \le 30,1 \le m \le 303≤n≤30,1≤m≤30

2008普及组第三题


首先蒟蒻用了BFS来打表找规律....嗯。。凉了,不难发现当前这个人的次数等于左右两人次数相加,用A[ i ] [ j ] 表示第i个人第k次的数目,值得一提的是两个for要先循环次数 后循环人数(想一下为什么),还有就是第1个人和n个人要特判一下


#include<bits/stdc++.h>
using namespace std;
#define maxn 40005
typedef long long ll;
ll n,m,A[35][35];
int main()
{
    ios::sync_with_stdio(false);
    A[1][0]=1;
    cin >> n >> m;
    for(ll i = 1; i <= 31; i++)
    {
        for(ll j = 1; j <= 31; j++)
        {
            if(j == 1)
                A[j][i] = A[n][i-1] + A[2][i-1];
            else if(j == n)
                A[j][i] = A[1][i-1] + A[n-1][i-1];
            else
                A[j][i] = A[j-1][i-1] + A[j+1][i-1];
        }
    }
    cout<<A[1][m]<<endl;
    return 0;
}

 

<think>好的,用户想了解如何用C++实现递推关系程序,需要示例代码。首先,我得明确什么是递推关系。递推关系通常指的是通过已知的前几个项,按照一定的规律计算出后续项的方法。这和递归不同,递推通常是迭代进行的,从初始条件开始一步步推导,而递归则是函数自己调用自己。 用户提供的引用中,引用[2]提到了递归计算斐波那契数列的例子,但用户现在问的是递推。所以需要区分递归和递推的区别,并给出递推的实现方式。斐波那契数列同样可以用递推来实现,比如用循环而不是递归,这样效率更高,因为递归会有重复计算的问题。 接下来,我需要考虑递推关系的一般实现步骤。通常步骤包括:确定初始条件、确定递推公式、使用循环结构迭代计算。例如斐波那契数列的递推公式是F(n) = F(n-1) + F(n-2),初始条件是F(0)=0,F(1)=1。用循环从2开始计算到n,每次保存前两项的值,这样可以避免递归的重复计算。 然后,我需要举一个例子,比如斐波那契数列的递推实现,并给出C++代码示例。代码中需要包括输入n,处理初始条件,循环计算,并输出结果。同时,要对比递推和递归的效率,说明递推的优势,比如时间复杂度是O(n),而递归是指数级的。 另外,用户提供的引用里有关于代码格式和缩进的引用[3],所以在编写示例代码时需要注意代码的可读性,合理使用缩进和空行。例如,在循环和条件语句中使用正确的缩进,函数之间用空行分隔,这样代码更清晰。 用户可能还关心递推的其他应用场景,比如阶乘计算、动态规划问题等。可以简要提到这些,但主要聚焦在斐波那契数列的例子。同时,根据用户问题中的系统级指令,需要生成相关问题,比如递推与递归的区别、优化方法、应用场景等。 最后,确保回答结构清晰,分步骤说明实现方法,代码正确且符合C++语法,并引用相关参考资料中的内容,如引用[2]和引用[3]来支持递归与递推的对比以及代码格式的重要性。</think>### C++递推关系程序实现方法 递推程序的核心是通过已知初始条件和递推公式,使用循环结构逐步推导出目标结果。以下是实现递推关系的典型步骤: 1. **确定递推关系式** 例如斐波那契数列的递推公式:$F(n) = F(n-1) + F(n-2)$ 2. **设置初始条件** 如$F(0)=0,\ F(1)=1$ 3. **选择存储结构** 使用数组或变量暂存中间结果 4. **迭代计算** 通过循环结构实现递推过程 ```cpp #include <iostream> using namespace std; int fibonacci_iterative(int n) { if(n <= 1) return n; int a = 0, b = 1, temp; for(int i = 2; i <= n; ++i) { temp = a + b; a = b; b = temp; } return b; } int main() { int n; cout << "请输入项数:"; cin >> n; cout << "斐波那契数列第" << n << "项为:" << fibonacci_iterative(n) << endl; return 0; } ``` ### 关键点解析 - **时间复杂度**:递推实现为$O(n)$,显著优于递归的$O(2^n)$[^2] - **空间优化**:仅用两个变量存储中间状态,空间复杂度$O(1)$ - **边界处理**:单独处理n=0和n=1的情况保证程序健壮性 - **代码结构**:合理缩进和空行提升可读性[^3] ### 递推与递归对比 | 特性 | 递推实现 | 递归实现 | |-----------|------------|------------| | 时间复杂度 | $O(n)$ | $O(2^n)$ | | 空间复杂度 | $O(1)$ | $O(n)$ | | 可读性 | 结构清晰 | 直观简洁 | | 适用场景 | 大规模计算 | 小规模问题 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值