动态硬币变换算法(最优结果)

时间:2013-02-23 11:10:43

标签: java algorithm data-structures dynamic-programming

我已经获得了动态编程的这部分代码(它找到了硬币变化的最佳组合。例如,如果我们有两个值为3和4的硬币 - > {3,4};以及金额我们想要改变是例如sum = 11,答案是我们需要总共3个硬币(2个硬币值= 4和1个硬币,值= 3)。下面的代码工作正常,但不完全像我希望如此。

我试图对下面的代码进行逆向工程,以便提供更清晰的答案:

Total coins:3 , #of Coins with value "3" = 1, #of Coins with value "4" = 2

给定数量的总硬币数可以从该数组最小值[sum]中找到。     但我想要得到的其余信息(哪个硬币是什么价值),似乎几乎不可能找到。同样来自阵列硬币[sum] [0]我只能找到最后使用的硬币,在这个例子中它是3。

Inputs: sum=11 ,int[] valueCoins = new int[]{3,4}; 
Output:
1 10011 0(0)
2 10011 0(0)
3 1 3(0)
4 1 4(0)
5 10011 0(0)
6 2 3(3)
7 2 3(4)
8 2 4(4)
9 3 3(6)
10 3 3(7)
11 3 3(8)

正如你所看到的,它检查从1到11的所有内容,但随后达到11它会存储正确数量的硬币(3)和最后使用的硬币(3)。

public class MinimumCoin {

    public static void main(String args[]){

        int[] valueCoins = new int[]{3,4};
        int sum = 11;
        int[] minimum = new int[sum+1];
        int[][] coins = new int[sum+1][2];

        /* initializing the minimum of every sum to infinity */
        for(int i = 1; i < minimum.length; i++){
            minimum[i] = sum + 10000;
        }
        /* initializing that for minumum sum of zero, 0 coin is required */
        minimum[0] = 0;

        for(int i = 1; i <= sum; i++){
            for(int j = 0; j <valueCoins.length; j++){
                if(valueCoins[j] == i){
                    minimum[i] = 1;
                    coins[i][0] = i;
                    coins[i][1] = 0;
                }
                else if((valueCoins[j] < i) && (((minimum[i-valueCoins[j]]) + 1) < minimum[i])){

                    minimum[i] = (minimum[i-valueCoins[j]]) + 1;
                    coins[i][0] = valueCoins[j];
                    coins[i][1] = (i-valueCoins[j]);
                }
            }
        }

        for(int k = 1; k < minimum.length; k++){
            System.out.println( k + " " + minimum[k] + " " + coins[k][0] +"("+ coins[k][1] +")");
        }
    }
}

感谢任何输入!

〜问候,S

1 个答案:

答案 0 :(得分:1)

问题是coins中的值是硬币的,而不是计数。 coins

0 0 0 3 0 0 3 3 4 3 3 3 
0 0 0 0 4 0 3 4 4 6 7 8

所以你需要重建计数:

for(int k = 1; k < minimum.length; k++)
{
   int count1 = 0, count2 = 0, pos = k;
   if (coins[pos][1] > 0)
      while (true)
      {
         if (coins[pos][0] == 3) count1++;
         if (coins[pos][0] == 4) count2++;
         if (coins[pos][1] == 3) count1++;
         if (coins[pos][1] == 4) count2++;
         if (coins[pos][1] < 5) // stop when 0/3/4
            break;
         pos = coins[pos][1];
      }
   System.out.println(k + " " + minimum[k] + " " +
                      count1 + " of coin 3, " + count2 + " of coin 4");
}

这些也是解决问题的选项:

  • 为每个硬币出现次数设置行。如果您有2个硬币,每个硬币可以出现5次,那么您将拥有5x2 = 10行。

  • 拥有如下行:

    • 第1行= 1投币1
    • 第2行=硬币2的1
    • 第3行=硬币1的2
    • 第4行=硬币2的2
    • 第5行=硬币1的4
    • 第6行=硬币2的4
    • 第7行=硬币1的8
    • 第8行=硬币2的8
    • ...

后者稍微复杂一些,但更受欢迎,因为对于更多硬币,行数会少得多。