Algorithm 对于给定的硬币数量,如果所有硬币管都有64个硬币,但不需要填充硬币管,则应尽量减少硬币管的数量

Algorithm 对于给定的硬币数量,如果所有硬币管都有64个硬币,但不需要填充硬币管,则应尽量减少硬币管的数量,algorithm,language-agnostic,Algorithm,Language Agnostic,编辑:如果有人能对著名的硬币兑换问题提供一个解释性的递归答案(链接就可以了),这将非常有帮助 对于给定的硬币数量,如果所有硬币管都能容纳64枚硬币,则应尽量减少硬币管的数量 每根管子只能装一种硬币 每根管子不需要完全充满 e、 g.对于美国硬币,金额分别为0.01美元、0.05美元、0.10美元、0.25美元、0.50美元和1美元 6美分可以在一根管子里作为6美分的硬币 25美分可以是一个装有一枚25摄氏度硬币的管子,也可以是一个装有五枚5摄氏度硬币的管子 65美分将作为13 5c硬币,因为

编辑:如果有人能对著名的硬币兑换问题提供一个解释性的递归答案(链接就可以了),这将非常有帮助


对于给定的硬币数量,如果所有硬币管都能容纳64枚硬币,则应尽量减少硬币管的数量

每根管子只能装一种硬币

每根管子不需要完全充满


e、 g.对于美国硬币,金额分别为0.01美元、0.05美元、0.10美元、0.25美元、0.50美元和1美元

6美分可以在一根管子里作为6美分的硬币

25美分可以是一个装有一枚25摄氏度硬币的管子,也可以是一个装有五枚5摄氏度硬币的管子

65美分将作为13 5c硬币,因为65 1c硬币需要使用2根管子


我正在尝试编写一个minecraft插件,但我在使用该算法时遇到了很多困难。

类似这样的内容:

a[0] = 100; //cents
a[1] = 50; a[2] = 25; a[3] = 10; a[4] = 5; a[5] = 1;

cnt[6]; //array to store how much coins of type i you use;


void rec(sum_left, p /* position in a array */) {
   if ( p == 5 ) {
      cnt[5] = sum_left;
      //count how many tubes are used by cnt array, update current answer if neccessary;
      return;
   }
   for ( int i = 0; i <= sum_left/a[p]; i++ )
      //take i coins of type a[p]
      rec(sum_left - i*a[i], p+1);
}

int main() {
   rec(sum, 0);
}
a[0]=100//美分
a[1]=50;a[2]=25;a[3]=10;a[4]=5;a[5]=1;
cnt[6]//数组以存储您使用的i型硬币数量;
void rec(左和,数组中的p/*位置*/){
如果(p==5){
cnt[5]=左和;
//计算cnt阵列使用的管数,必要时更新当前答案;
返回;
}

对于(inti=0;i而言,查找表是一种很好的方法

int[]硬币=新[]{100,50,25,10,5,1};
int[,]表=新int[66400];
///计算每种类型的硬币数量,使硬币数量最小化
///使用的管子。
整数[]管(整数分)
{
整数[]计数=新整数[硬币长度];
如果(美分>=6400)
{
计数[0]+=(美分/6400)*64;//填充的1美元管中的硬币数量
仙%=6400;
}
对于(int i=0;i
要计算表格,可以使用以下公式:

void CalculateTable()
{
对于(int i=Coins.Length-1;i>=0;i--)
{
int硬币=硬币[i];
用于(整数分=0;分<6400;分++)
{
如果(i==硬币长度-1)
{
//1美分的硬币不能再分了
表[i,美分]=美分;
}
其他的
{
//找到使管数最小化的计数。
整数n=美分/硬币;
int=1;
int-bestCount=0;
对于(整数计数=美分/硬币;计数>=0;计数--)
{
int cents1=美分-计数*硬币;
整数管=(计数+63)/64;
//使用上面Tubes()中的算法优化
//较小的硬币。
对于(int j=i+1;j
CalculateTable
将在几毫秒内运行,因此您不必将其存储到磁盘

示例:

管(3149)->[31,0,0,0,49]
管子(3150)->[0,63,0,0,0,0,0]
管子(31500)->[315,0,0,0,0,0]
这些数字表示硬币的数量。N枚硬币可以放入(N+63)/64个管子中。

这里是一个,和算法

在数组
T
中,每个
T[i]
包含6个整数的数组

如果给定的总和是
65
,则调用
tubes(65)
,然后
print T T[65]

coins[1..6] = {1, 5, 10, 25, 50, 100}

tubes(sum)
    if sum < coins[1]
        return
    for i = 1 to 6
        tubes(sum - coins[i])
    best-tubes[1..6] = {64, 64, 64, 64, 64, 64}
    for i = 1 to 6
        if sum - coins[i] >= 0
            current-tubes[1..6] = copy of T[sum - coins[i]]
            if current-tubes[i] < 64
                current-tubes[i] += 1
                if current-tubes is better than best-tubes*
                    best-tubes = current-tubes
    T[sum] = best-tubes
coins[1..6]={1,5,10,25,50,100}
管子(总数)
如果金额<硬币[1]
返回
对于i=1到6
管(总和硬币[i])
最佳管[1..6]={64,64,64,64,64,64}
对于i=1到6
如果总和硬币[i]>=0
电流管[1..6]=T的副本[总和硬币[i]]
如果电流管[i]<64
电流管[i]+=1
如果当前管优于最佳管*
最佳管=当前管
T[sum]=最佳管
若要大大改善运行时间,可以检查当前的
T[sum]
是否已被评估。添加此检查完成调用的方法


*
当前的电子管比最佳的电子管好
使用更少的电子管,或者使用更少硬币的相同数量的电子管,或者使用相同数量的电子管,但是电子管的值更大。这是贪婪的行动部分。

看起来简单的暴力方法应该足够好,除非你想处理非常大的问题大量的钱?老实说?我对编程非常陌生,不知道从哪里开始,我试着考虑以某种方式修改贪婪的方法,曾想过用暴力强迫解决问题,但我甚至很难获得给定数量的组合或找到一个示例(关于如何从数量中获得硬币组合)我可以理解。我刚刚发现了一个stackoverflow的例子,我可以遵循,所以我会很快更新。25美分的例子可以用25个1c硬币放在一个管子里吗?因为对于[5]=1,只有一个有效的变体可以得到硬币。不,我没有运行代码