我设法编写此代码以找到最小硬币总和以获得确切的数值。但是我在考虑积极的硬币价值时写了这个。
有人可以告诉我如何升级此代码以计算具有负硬币值的最小硬币总和吗? 提前谢谢!
int main()
{
int arr[] = {1, 2, 3};
int m = sizeof(arr)/sizeof(arr[0]);
int n = 4;
printf(" %d ", count(arr, m, n));
return 0;
}
int count( int S[], int m, int n )
{
int i, j, x, y;
int table[n+1][m];
for (i=0; i<m; i++)
table[0][i] = 1;
// Fill rest of the table enteries in bottom up manner
for (i = 1; i < n+1; i++)
{
for (j = 0; j < m; j++)
{
// Count of solutions including S[j]
x = (i-S[j] >= 0)? table[i - S[j]][j]: 0;
// Count of solutions excluding S[j]
y = (j >= 1)? table[i][j-1]: 0;
// total count
table[i][j] = x + y;
}
}
return table[n][m-1];
}
答案 0 :(得分:0)
目前尚不清楚您是否想要使用每个硬币任意次数(通常如何说明问题),或者您是否想要使用每个硬币只需0或1次(这是什么你的代码暗示)。
如果允许您使用每个硬币任意次数,那么概念上最简单的解决方案是在编号为0到N的节点上构建图形,其中N是所有正硬币值的总和,然后连接节点i如果(ji)是你的硬币值之一,则带有有向边的j,然后运行Dijkstra算法,其中所有边都具有权重1,以找到从0到图中所有其他节点的最短路径,其中包括目标价值。您可以回溯以找到针对目标值的特定最佳解决方案。
如果您只允许最多使用一次硬币,那么您可以假设一般性,即给定目标值的最佳解决方案将首先使用所有正硬币然后使用所有负硬币。因此,您可以使用所有正硬币(其中N是所有正硬币值的总和)使用广度优先搜索来建立值0到N的最佳解决方案,其中您可以跟踪制作每个目标值所需的硬币数量和在最优解决方案中使用的最后一枚硬币,然后订购正硬币然后一次拿一枚硬币,并考虑将每枚硬币添加到您当前可以获得的每个值,以查看是否可以使用较少数量的硬币获得新值硬币。然后在使用正硬币计算所有最优解后,您可以订购负值硬币,并类似地反向处理最佳解决方案阵列。