【问题标题】:Bytelandian Gold Coin explaination? [duplicate]Bytelandian金币解释? [复制]
【发布时间】:2015-06-23 05:44:53
【问题描述】:

我正在尝试这里提到的 Bytelandian 金币问题 - http://www.codechef.com/problems/COINS/ 这是它的解决方案之一 -

#include <stdio.h>
long int a[30][19];  //1
long int recur(long int n, int i, int j);
int main()
{
    long int n;
    int i, j;
    while (scanf("%lld", &n) != EOF)
    {
        for (i = 0; i < 30;i++)
        for (j = 0; j < 19; j++)
            a[i][j] = 0;
        long int v = recur(n, 0, 0);
        printf("%lld\n", v);
    }
    return 0;
}
long int recur(long int n, int i, int j)
{
    if (n <12 )  //2
        return n;
    else if (!a[i][j])
    {
        long int t = recur(n / 2, i + 1, j) + recur(n / 3, i, j + 1) + recur(n / 4, i + 2, j);
        a[i][j] = t;
    }

    return a[i][j];
}

在这段代码中,我无法理解两点- 1-数组 a[30][19] 的大小,它基于输入数的最大值可被 2 或 3 整除的最大次数,他们使用一些对数基数为 2 或 3 的公式来查找。可以有人请解释这个公式,如果是的话,这是一些数学属性我在哪里可以找到有关它的更多信息。 2-停止递归 n

long int recur(long int n, int i, int j)
{
    if ((n == 0) || (n == 1) || (n == 2) )
        return n;
    else if (!a[i][j])
    {
        long int t = recur(n / 2, i + 1, j) + recur(n / 3, i, j + 1) + recur(n / 4, i + 2, j);
        a[i][j] = n> t ? n : t;
    }

    return a[i][j];
}

如果有人请解释以上2点,我将不胜感激

【问题讨论】:

  • 注意:"%lld" 更改为 "%ld"long int
  • 我这样做了,但提交解决方案后得到了错误的答案。
  • a[27][17] 对于所有用例

标签: c recursion dynamic-programming memoization


【解决方案1】:
  1. i 的上限来自条件 2i ≤ 109( 109 可以除以 2 直到达到 1 的次数等于 1 可以乘以 2 直到达到 109 的次数);求解 i 得到 i ≤ log2(109) ≅ 29.9。
    另一种看待它的方法是将 109 表示为二进制数 1110111001101011001010000000002;这个数字有 30 位,每个整数除以 2 会减少一位(删除最右边的数字),所以经过 29 次除法后,我们得到 1。
    正如 JohnH 在上面的评论中正确指出的那样,i 的最大值仍然低于 29,因为递归不会下降到 n 等于; 1,但停在 n 。
    j 的上限和除以 3 的情况大致相同。 109 作为三进制数是 21202002000210100013;这个数字有 19 位数字;在 17 次整数除以 3 后,我们得到 213 等于; 7,递归停止的地方。

  2. 要找出12以下的所有数字都等于它们的最大兑换金额,我们可以简单地尝试一下:

    n n/2 n/3 n/4 3 个交换硬币的总和 1 0 0 0 0 2 1 0 0 1 3 1 1 0 2 4 2 1 1 4 5 2 1 1 4 6 3 2 1 6 7 3 2 1 6 8 4 2 2 8 9 4 3 2 9 10 5 3 2 10 11 5 3 2 10 12 6 4 3 13

    我们看到 12 是在交换时产生的值高于自身的最小数字。

    如果我用这个替换了原来的 recur 函数,我就错了 回答-

    n &equals; 509607936 你得到“错误答案”,因为long int t 等溢出到负值。奇怪的是,在原来的recur 函数中,这个错误被另一个错误所补偿,即BLUEPIXY 指出的错误转换规范%lld。该程序可以通过定义arecurtv 类型为unsigned long int 并使用适当的转换规范%lu 来纠正。

【讨论】:

    猜你喜欢
    • 2014-08-11
    • 1970-01-01
    • 2010-12-22
    • 1970-01-01
    • 1970-01-01
    • 2010-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多