`

金币问题

阅读更多

今年某公司的笔试题:

一个矩阵地图,每一个元素值代表金币数,玩家从左上角一直走到右下角,每次只能向下移动一格或是向右移动无数格后向下移动一格。当元素值为-1时,玩家无法移动到此格。玩家每移动到一格就可以获取这一格的金币数,求获得最大金币数。
很容易的一道动态规划题,动态转移方程

m[i][j] = max{m[i-1][j] + a[i][j], m[i-1][k] + a[i-1][j] + a[i][j]}  0 <= k < j

初始化:

#define MIN -1000000
int a[M][N];//金币矩阵
int m[M][N];//最大值矩阵

void init(){
    memset(m,0,sizeof(int) * M * n);
    int i,j,k;
    int sum = 0;
    for(i = 0; i < M; i++){//初始化第一列
        if(a[i][j] == -1){
            m[i][0] = MIN;
        }else{
            sum+=m[i][0];
            m[i][0] = sum;
        }
    }
   
    for(j = 0; j < N; j++){//初始化第一行
        if(a[0][j] == -1){
            m[0][j] = MIN;
        }else{     
             m[0][j] = a[0][j];
        }
    }
}

 

 

 从底往上递推代码:

int max_coin(){
    int i,j,k;
    for(i = 1; i < M; i++)
        for(j = 1; j < N; j++){
            int max =  m[i-1][j] + a[i][j];
            for(k = 0; k < j; k++){
                int coins = m[i-1][k] + a[i-1][j] + a[i][j];
                if(coins > max)
                    max = coins;
            }
        }
    return m[M-1][N-1];
}

 

 

直接记事本的方式递归,发现已经计算过直接返回的方式:

   int max_coin(int i,int j){
        if(m[i][j] != 0)//已经计算出来
            return m[i][j];
        else{
            int max = max_coin(i-1,j) + a[i][j];
            for(int k = 0; k < j; k++){
                t_m = max_coin(i,k) + a[i-1][j] + a[i][j]);
                if(max <  t_m)
                    max = t_m;
            }
            return max;
        }
    }

 

 

0
0
分享到:
评论
7 楼 lcwen08 2010-03-09  
"移动到一格才能得到金币,并不是移动经过的路径的金币都可以得到。"
原来如此,
6 楼 fuliang 2010-03-09  
lcwen08 写道

(i-1, k)点尽管最大,但它不一定能够到达(i-1, j)点..

这里将无法移动到的格设置到了一个最小值MIN,相当于负无穷,这样可以忽略掉不可到达的格子了,因为凡是移动到不可到达格的方案是不可能在求最大值中取胜的。
5 楼 fuliang 2010-03-09  
lcwen08 写道
不过,我又想了想,方程好像应该这样写:
m[i][j] = max { m[i-1][k] + a[i-1][k+1] + ... + a[i-1][j]} + a[i][j]
其中 (0 <= k < j),
这里:
int coins = m[i-1][k] + a[i-1][j] + a[i][j];
(i-1, k)点尽管最大,但它不一定能够到达(i-1, j)点..

这个可能是下面这句话你理解的偏差:
引用
玩家每移动到一格就可以获取这一格的金币数

移动到一格才能得到金币,并不是移动经过的路径的金币都可以得到。
4 楼 lcwen08 2010-03-09  
不过,我又想了想,方程好像应该这样写:
m[i][j] = max { m[i-1][k] + a[i-1][k+1] + ... + a[i-1][j]} + a[i][j]
其中 (0 <= k < j),
这里:
int coins = m[i-1][k] + a[i-1][j] + a[i][j];
(i-1, k)点尽管最大,但它不一定能够到达(i-1, j)点..
3 楼 lcwen08 2010-03-09  
哈哈,明白了,原来每次都必须得向下移动一格啊
2 楼 fuliang 2010-03-09  
lcwen08 写道
我是初学者,可能考虑的有问题,请指教:
如果m[i][j-1] > m[i-1][j],是不是要取:
   m[i][j] = m[i][j-1] + a[i][j] ?
解法中好像不是啊..

从m[i][j-1]到m[i][j]是不可达的,所以没有你说的那种情况,原因是题目中说:
每次只能向下移动一格或是向右移动无数格后向下移动一格
1 楼 lcwen08 2010-03-09  
我是初学者,可能考虑的有问题,请指教:
如果m[i][j-1] > m[i-1][j],是不是要取:
   m[i][j] = m[i][j-1] + a[i][j] ?
解法中好像不是啊..

相关推荐

    金币阵列问题(完整的源程序C++)

    【金币阵列问题】是一个经典的计算机算法问题,主要涉及到数组操作和动态规划。在这个问题中,我们有一个m行n列的二维数组,其中数组的每个元素代表一枚金币的状态,0表示正面朝上,1表示背面朝上。游戏的规则允许两...

    C++代码假金币

    假金币问题通常涉及到数组或集合中的元素,其中一部分元素代表正常的硬币,而另一部分是假的,具有不同的特性。例如,假金币可能重量不同,或者具有某种特殊标识。目标是找出所有的假金币,而只能通过有限次的操作或...

    信息学奥赛一本通1100:金币.mp4

    信息学奥赛一本通1100:金币.mp4

    金币阵列问题算法c源代码

    问题描述:有n*m(m,n)枚金币在桌面上排成一个 n 行 m 列的金币阵列。每一枚金币或正面朝上,或背面朝上。 用数字表示金币状态,0表示金币正面朝上,1表示金币背面朝上。 金币阵列的游戏规则是: (1) 每次可将...

    金币阵列问题

    【金币阵列问题】是一个经典的计算机科学中的优化问题,它涉及到数组操作和状态转换策略。问题的核心在于如何通过有限次的特定操作将一个给定的金币阵列转换为另一个目标阵列,同时使得操作次数最小。 在这个问题中...

    算法-金币(信息学奥赛一本通-T1100)(包含源程序).rar

    1. **搜索算法**:在解决金币问题时,可能会用到深度优先搜索(DFS)或广度优先搜索(BFS)。例如,如果问题是要找到最优的金币收集路径,那么搜索算法可以遍历所有可能的路径并找到最佳解。 2. **动态规划**:动态...

    骑士问题 C++代码

    用C++写的简单的骑士问题,写的一般,望指教。

    1.5编程基础之循环控制_45_金币(2019.09.11).pdf

    本文所述的金币问题,是一个典型的循环控制问题,它可以通过编程语言中的循环结构来解决。问题描述中提到的金币发放规则为:“第一天骑士收到1枚金币;之后每增加2天,每天收到的金币数增加1枚。”根据这个规则,...

    算法设计与分析之金币陈列问题

    有m´ n(m £ 100,n £ 100)个金币在桌面上排成一个m行n 列的金币阵列。每一枚金币或正面朝上或背面朝上。用数字表示金币状态,0表示金币正面朝上,1 表示背面朝上。 金币阵列游戏的规则是: (1)每次可将任一行...

    仿淘宝金币掉落撒落动画

    过多的动画元素可能会导致性能问题,特别是在移动设备上。因此,开发者需要合理控制金币的数量,优化渲染过程,比如使用精灵表(Sprite Sheet)来减少内存占用和渲染次数。 总的来说,仿淘宝金币掉落撒落动画涉及到...

    vc.zip_金币阵列问题

    【金币阵列问题】是一种经典的计算机算法设计与分析的题目,它主要涉及到数组处理、动态规划、最优化问题等核心算法概念。在这个问题中,我们通常假设有一个二维金币阵列,每个位置上都有一定数量的金币,目标是设计...

    QT学习之翻金币源代码及参考资料

    QT学习之翻金币源代码及参考资料是一份针对QT框架的学习资源,特别适合对QT感兴趣的初学者和开发者。这个小游戏展示了如何使用C++编程语言...同时,提供的参考资料将进一步辅助理解和学习过程,帮助解决遇到的问题。

    算法分析与基础---蛮力法

    【问题】:假金币问题是一个典型的利用蛮力法解决的例子。在这个问题中,银行需要识别出M组金币中每组的假金币,每组至少有一个假金币且重量不同。银行只有一个天平,可以比较两组金币的重量。我们的任务是根据称量...

    算法设计求金币阵列问题

    ### 算法设计求金币阵列问题解析 #### 问题背景与定义 在一个由`m×n`(其中`m ≤ 100`, `n ≤ 100`)个金币组成的矩阵中,每个金币可以是正面朝上(表示为`0`)或者背面朝上(表示为`1`)。玩家的目标是从一个...

    经典逻辑,面试题,逻辑问题

    除此之外,还有一些其他类型的逻辑问题,如飞机加油问题、推理对话、强盗分金币问题、自然数和的推理、烧绳子计时、果冻抓取、称水问题、岔路口问题、天平找不同重量球的问题、画直线问题、时针分针秒针重合问题,...

    淘金币抵钱怎么用|一键淘金币软件 v1.0.zip

    "淘金币抵钱怎么用"这个问题涉及到淘宝购物过程中的一个关键环节,即如何有效地利用淘金币进行支付抵扣。 淘金币的使用规则如下: 1. **获取方式**:淘金币主要通过在淘宝购物、参与店铺活动、签到、浏览商品、评价...

    淘金币助手1

    淘金币助手1是一款专为淘宝用户设计的辅助工具,旨在帮助用户更轻松地管理和获取淘宝平台上的淘金币。淘金币是淘宝网推出的一种虚拟货币,用户可以通过参与...了解如何正确处理这类问题对于确保软件顺利运行至关重要。

    Python小游戏源码-接金币游戏游戏源码

    【Python小游戏源码-接金币游戏游戏源码】 ...同时,这个过程也能帮助你提升编程技巧,包括逻辑思维、问题解决以及代码优化等方面。如果你对游戏开发感兴趣,那么从这个简单的项目开始,无疑是一个很好的起点。

Global site tag (gtag.js) - Google Analytics