【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;
}
相关推荐
有意义2 小时前
深度拆解分割等和子集:一维DP数组与倒序遍历的本质
前端·算法·面试
用户726876103373 小时前
解放双手的健身助手:基于 Rokid AR 眼镜的运动计时应用
算法
Wect3 小时前
LeetCode 17. 电话号码的字母组合:回溯算法入门实战
前端·算法·typescript
ZhengEnCi1 天前
08c. 检索算法与策略-混合检索
后端·python·算法
程序员小崔日记1 天前
大三备战考研 + 找实习:我整理了 20 道必会的时间复杂度题(建议收藏)
算法·408·计算机考研
lizhongxuan1 天前
AI小镇 - 涌现
算法·架构
AI工程架构师1 天前
通常说算力是多少 FLOPS,怎么理解,GPU和CPU为什么差异这么大
算法
祈安_1 天前
Java实现循环队列、栈实现队列、队列实现栈
java·数据结构·算法
归去_来兮2 天前
拉格朗日插值算法原理及简单示例
算法·数据分析·拉格朗日插值
千寻girling2 天前
Python 是用来做 AI 人工智能 的 , 不适合开发 Web 网站 | 《Web框架》
人工智能·后端·算法