Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 动态规划中的核心转储错误_C++_Dynamic Programming_Memoization - Fatal编程技术网

C++ 动态规划中的核心转储错误

C++ 动态规划中的核心转储错误,c++,dynamic-programming,memoization,C++,Dynamic Programming,Memoization,我正在修改一个程序,该程序可以确定给定数量的零钱所需的最少硬币数量。这种硬币系统只有三枚硬币:$0.01、$0.06、$0.10。所以13美分,如果硬币是3的话,最小的数字是3。对于56美分,最小数字是6,等等。程序做这部分,我的部分是回溯备忘录表以确定使用的每个硬币的数量。例如,13美分的最低值是3枚硬币,这些硬币是2枚6美分的硬币和1枚1美分的硬币 下面生成的备注表如下所示: 1cent 0 1 2 3 4 5 6 7 8 9 10 11 12 13 6cent 0 1 - 3 - -

我正在修改一个程序,该程序可以确定给定数量的零钱所需的最少硬币数量。这种硬币系统只有三枚硬币:$0.01、$0.06、$0.10。所以13美分,如果硬币是3的话,最小的数字是3。对于56美分,最小数字是6,等等。程序做这部分,我的部分是回溯备忘录表以确定使用的每个硬币的数量。例如,13美分的最低值是3枚硬币,这些硬币是2枚6美分的硬币和1枚1美分的硬币

下面生成的备注表如下所示:

1cent  0 1 2 3 4 5 6 7 8 9 10 11 12 13
6cent  0 1 - 3 - - - 2 - -  -  -  -  3
10cent 0 - - 3 - - - - - -  -  -  -  3
对于这样的事情,我们总是从右下角开始。我试图递归地做这件事。我注意到一种模式。如果我们有一个数字,而上面的数字不是同一个数字,那么我们“跳”到同一行的左边
cent
空格。所以在最下面的一行,10美分,在最后我们看到从13跳到3,也就是10个空格。如果一个数字和上面的数字是同一个数字,这意味着硬币在多次使用后停止使用,我们向上移动一行。因此,在上表中,我们从右下角开始,
3
。正上方的数字也是一个
3
,因此,由于出现了0次“跳跃”,因此使用的10美分硬币的数量是0,我们向上移动到下一行,即
6美分

现在我们比较
3
13
。这两个数字不相等,所以我们在
6
空间上移动。因此,我们现在有了
1
“跳跃”。现在我们来看
2
7
。这两个也不相等,所以我们移动了
6
更多的空间,现在我们有了
2
“跳跃”。现在我们比较
1
1
,它们相等,所以我们向上移动一行,从该点开始。由于过去这一行中有
2
“跳跃”,因此使用的
6美分
硬币数量为
2
。最后一部分让人困惑。当我们向上移动一行时,我们从同一列开始。由于我们比较了
1
1
,我们将从该专栏继续。因为这是最后一行,行
0
,所以剩余的更改量将始终是顶部的数字。在我的例子中,我们上移了一行,从
1
开始,因此使用的
1美分
硬币的数量是
1
。这意味着使用的硬币总数为:

 1 cent: 1
 6 cent: 2
10 cent: 0
我知道这是一个非常混乱的措辞。希望我的代码能更好地显示这一点。下面是我如何尝试实现这一点的:

void countCoins( uint i, uint a, uint coinVal,
                 const vector< uint > & denom,
                 Matrix< uint > & memo )
{
   uint numCoins = 0;

   // Check the current value with the value above it
   if( memo.at(i, a) != memo.at(i - 1, a) )
   {
      if( denom.at(i) == coinVal )
      {
         numCoins++;
      }

      countCoins( i, a - denom.at(i), coinVal, denom, memo );    // If not equal, "jump" over
   }
   else
   {
      if( i > 0 )
      {
         countCoins( i - 1, a, coinVal, denom, memo );    // If equal, move up a row
      }
      else
      {
         numCoins += a;    // If equal and the row number is 0
      }
   }
}
void countCoins(uint i、uint a、uint coinVal、,
常量向量&denom,
矩阵(备忘录)
{
uint numCoins=0;
//检查当前值及其上方的值
if(memo.at(i,a)!=memo.at(i-1,a))
{
如果(在(i)处的名称=coinVal)
{
numCoins++;
}
countCoins(i,a-denom.at(i),coinVal,denom,memo);//如果不相等,“跳过”
}
其他的
{
如果(i>0)
{
countCoins(i-1,a,coinVal,denom,memo);//如果相等,则上移一行
}
其他的
{
numCoins+=a;//如果相等且行号为0
}
}
}
这段代码可以编译,但当我运行它时,会收到一条消息,上面写着:“matrix.h:48:Object&matrix::at(uint,uint)[with Object=unsigned int;uint=unsigned int]:断言'row我不知道为什么。有人知道我为什么会收到这个核心转储消息吗?

在尝试访问
memo
和/或
denom
之前,您需要检查
I
a
是否小于
0

void countCoins( uint i, uint a, uint coinVal,
                 const vector< uint > & denom,
                 Matrix< uint > & memo )
{
    if (i < 0) {
        // handle edge case and return
    }

    if (a < 0) {
        // handle edge case and return
    }

    uint numCoins = 0;

    ...
    ...

}
void countCoins(uint i、uint a、uint coinVal、,
常量向量&denom,
矩阵(备忘录)
{
if(i<0){
//处理封边盒并返回
}
if(a<0){
//处理封边盒并返回
}
uint numCoins=0;
...
...
}

注意:如果
i
a
的值可能高于
memo
denom
的大小,则还需要检查该值。但是在你的代码中,你似乎总是在减少它们,所以情况可能不是这样

我很难理解您的逻辑,但是您的行或列的索引值是否可能在某个点为负或为空?请编辑您的问题并包括一个。是的,我确信我的逻辑很难理解。这在我的脑海里很有道理,但解释起来很难。我试着输入调试语句来打印行和列的索引,它们似乎是正确的。对于每个单元格,您需要记录最小硬币数和用于到达它的硬币数。然后你可以从任何选择的面额开始,沿着桌子走回去。