【NC16619】传球游戏

题目

传球游戏

动态规划

思路

这道题主要考察对状态转移的理解。说实话,动态规划问题只要想到了就简单,想不到就很难,除了像背包问题那一类有固定套路的题以外,其实大部分的动态规划问题都没什么所谓的公式。还是得多练,多见识不同的题型才能更好地思考动态规划问题。

题目中给定了 n n n 个人组成一个环,要求从第 x x x 个人开始,经过 m m m 次传球之后球又回到第 x x x 个人手中的不同方法数。其中 x x x 表示球最开始在的那个人,题目中是小蛮,这可以认为是一个定值。

首先需要明确的是,假设我现在身处这个环中,要接到球有几种可能?只有两种可能,要么从右边的人手中接到球,要么从左边的人手中接到球

其实如果最开始就是往这个方向想的话,那么离正确答案也就不远了。但是我也是这么想的,却没有得到正确答案,原因是什么呢?就是那种"感觉"没有培养到位,换句话说:题练少了。

明确了这一点之后,那么显然 ,球到我手里的不同方法数,其实就是球到我左边的人手里的方法数 + + + 球到我左边的人手里的方法数。

这样一来就有递推的感觉了,也就有动态规划的影子了。

那么按照动态规划的模板思考:

设置一个 d p [ i ] [ j ] dp[i][j] dp[i][j] 数组表示经过 i i i 次传球球又回到编号为 j j j 的人手中的不同方法数。则状态转移方程为:
d p [ i ] [ j ] = d p [ i − 1 ] [ ( j − 1 + n ) % n ] + d p [ i − 1 ] [ ( j + 1 ) % n ] dp[i][j]=dp[i-1][(j-1+n)\%n]+dp[i-1][(j+1)\%n] dp[i][j]=dp[i−1][(j−1+n)%n]+dp[i−1][(j+1)%n]

注意是环形的,要取模。式子中的 % \% % 表示取模。

假设小蛮的编号为 0 0 0,那么最终的答案就是 d p [ m ] [ 0 ] dp[m][0] dp[m][0],即传了 m m m 次球球又回到编号为 0 0 0 的人手中。边界条件为 d p [ 0 ] [ 1... n − 1 ] = 0 , d p [ 0 ] [ 0 ] = 1 dp[0][1...n-1]=0,dp[0][0]=1 dp[0][1...n−1]=0,dp[0][0]=1,因为初始球就在编号为 0 0 0 的人手中,经过 0 0 0 次传球,不同的方法数为 1 1 1(球没动)

有了上面的思路就可以写出代码并解决问题了。但是不应满足于此,动态规划问题往往可以用滚动数组优化,这道题也行,具体见代码。

代码

cpp 复制代码
#include <stdio.h>

int main(void) {
    int n = 0, m = 0;
    scanf("%d%d", &n, &m);
    // 滚动数组,只保留两行,然后用奇偶性进行切换
    int dp[2][n], i = 0, j = 0, idx = 0;
    // 初始化
    for (i = 0; i < n; i++) {
        dp[0][i] = 0;
    }
    // 小蛮为0号
    dp[0][0] = 1;
    for (i = 1; i <= m; i++) {
        for (j = 0; j < n; j++) {
            idx = i & 1;  // idx仅仅是为了简化代码写法,可以去掉
            dp[idx][j] = dp[!idx][(j - 1 + n) % n] + dp[!idx][(j + 1) % n];
        }
    }
    printf("%d\n", dp[m & 1][0]);
    return 0;
}
相关推荐
沐怡旸5 分钟前
【算法】725.分割链表--通俗讲解
算法·面试
L_09071 小时前
【Algorithm】Day-4
c++·算法·leetcode
代码充电宝1 小时前
LeetCode 算法题【简单】20. 有效的括号
java·算法·leetcode·面试·职场和发展
海琴烟Sunshine1 小时前
leetcode 119. 杨辉三角 II python
算法·leetcode·职场和发展
小杨的全栈之路1 小时前
霍夫曼编码:数据压缩的核心算法详解(附图解 + 代码)
算法
cjinhuo2 小时前
标签页、书签太多找不到?AI 分组 + 拼音模糊搜索,开源插件秒解切换难题!
前端·算法·开源
贝塔实验室2 小时前
频偏估计方法--快速傅里叶变换(FFT)估计法
网络协议·算法·数学建模·动态规划·信息与通信·信号处理·傅立叶分析
闭着眼睛学算法2 小时前
【双机位A卷】华为OD笔试之【模拟】双机位A-新学校选址【Py/Java/C++/C/JS/Go六种语言】【欧弟算法】全网注释最详细分类最全的华子OD真题题解
java·c语言·javascript·c++·python·算法·华为od
玉夏3 小时前
【每日算法C#】爬楼梯问题 LeetCode
算法·leetcode·c#
学好statistics和DS3 小时前
【CV】泊松图像融合
算法·计算机视觉