精确变化UVA

时间:2016-06-14 11:53:48

标签: c++ algorithm dynamic-programming onlinejudge

我正在解决以下问题。

enter image description here

及其求解算法位于http://www.algorithmist.com/index.php/UVa_11517

伪算法:

int dp[30001];

dp[0] = 0;
for (int i=1; i<=30000; i++)
    dp[i] = INFINITE;

for each coin C do
    for (int v = 30001 - C - 1; v >= 0; v--)
        if (dp[v] < INFINITE)
            dp[v+C] = min(dp[v+C], dp[v]+1);

但我认为它的解决方案是错误的。 让我们来看看硬币面额的情况:

Coins = [500,1000,1500]

price = 3000。根据上述解决方案,其答案为3000 with 3 coins。但是可以从1500的2个硬币中获得3000。 请告诉我这个解决方案是错误还是正确。

1 个答案:

答案 0 :(得分:1)

建议的解决方案是正确的,因为您没有每种面额的无限数量的硬币:

  

[我]通常会带来现金。

     

以下n行每行包含一个整数,即每个账单或硬币的分数值。

这就是为什么提出的解决方案中的循环减少的原因:

$yearList = $command->queryRow();

这避免了使用相同的硬币两次,因为当它for (int v = 30001 - C - 1; v >= 0; v--) 构建dp[v]时,dp[v+C]已经构建而不使用当前的硬币C.

此外,为了允许任何次数使用任何硬币,逆转此循环就足够了:

dp[v]