English 中文(简体)
A. 动态方案拟订—变革决定
原标题:Dynamic programming - Coin change decision

我用算法课程对一些老笔记进行审查,而动态的方案拟订问题似乎对我来说是一个小.。 我有一个问题,即我们有无限的 co供应,有些教派为x1、x2、......xn,我们希望改变某种价值X。 我们正试图设计一个动态方案,以决定能否改变X(而不是尽可能减少表兄弟的数量,或归还哪些表兄弟,即真实的或虚假的)。

我已经对这个问题做了一些思考,我可以看到,如果它像......这样做的话,那是一次令人厌恶的做法。

MakeChange(X, x[1..n this is the coins])
    for (int i = 1; i < n; i++)
    {
        if ( (X - x[i] ==0) || MakeChange(X - x[i]) )
            return true;
    }
    return false;

改变这一动态方案并不容易到我来。 我怎么能这样做?

最佳回答

你的法典是一个良好的开端。 改用动态方案拟订办法的通常办法是“自下而上”而不是“从上而下”。 也就是说,如果你的宽恕解决办法使用小X的数值计算出某个特定X的某种东西,那么就算出同一东西从小X开始,并将其列入一个表格。

阁下, 将休养职能改为“智库”。

canMakeChange[0] = True
for X = 1 to (your max value):
   canMakeChange[X] = False
   for i=1 to n:
     if X>=x[i] and canMakeChange[X-x[i]]==True: 
       canMakeChange[X]=True
问题回答

我的以下解决办法是计算所有解决办法和满足最新最佳解决办法的贪.办法。 如果目前的执行办法已经比紧凑的解决方案大,无法走路。 值得注意的是,最佳表现的派别应处于下降状态。

import java.util.ArrayList;
import java.util.List;

public class CoinDenomination {

    int denomination[] = new int[]{50,33,21,2,1};
    int minCoins=Integer.MAX_VALUE;
    String path;

    class Node{
        public int coinValue;
        public int amtRemaining;
        public int solutionLength;
        public String path="";
        public List<Node> next;

        public String toString() { return "C: "+coinValue+" A: "+amtRemaining+" S:"+solutionLength;}
    }

    public List<Node> build(Node node)
    {
        if(node.amtRemaining==0)
        {
            if (minCoins>node.solutionLength) {
                minCoins=node.solutionLength;
                path=node.path;
            }
            return null;
        }

        if (node.solutionLength==minCoins) return null;
        List<Node> nodes = new ArrayList<Node>();
        for(int deno:denomination)
        {
           if(node.amtRemaining>=deno)
           {
               Node nextNode = new Node();
               nextNode.amtRemaining=node.amtRemaining-deno;
               nextNode.coinValue=deno;
               nextNode.solutionLength=node.solutionLength+1;
               nextNode.path=node.path+"->"+deno;
               System.out.println(node);
               nextNode.next = build(nextNode);
               nodes.add(node);

           }
        }

        return nodes;
    }

    public void start(int value)
    {
        Node root = new Node();
        root.amtRemaining=value;
        root.solutionLength=0;
        root.path="start";
        root.next=build(root);
        System.out.println("Smallest solution of coins count: "+minCoins+" 
Coins: "+path);
    }

    public static void main(String args[])
    {
        CoinDenomination coin = new CoinDenomination();
        coin.start(35);
    }
}

只是为复读解决办法增加一个改观步骤,动态算法是正确的。 下面的例子就是:

cache = {}
def makeChange(amount, coins):
    if (amount,coins) in cache:
        return cache[amount, coins]
    if amount == 0:
        ret = True
    elif not coins:
        ret = False
    elif amount < 0:
        ret = False 
    else:
        ret = makeChange(amount-coins[0], coins) or makeChange(amount, coins[1:])
    cache[amount, coins] = ret
    return ret

当然,你可以使用电解器实现自动消化,从而形成更自然的法典:

def memoize(f):
    cache = {}
    def ret(*args):
        if args not in cache:
            cache[args] = f(*args)
        return cache[args]
    return ret
@memoize
def makeChange(amount, coins):
    if amount == 0:
        return True
    elif not coins:
        return False
    elif amount < 0:
        return False
    return makeChange(amount-coins[0], coins) or makeChange(amount, coins[1:])

注:即便是你所张贴的非动态格式版本,也存在各种最先进的案件。 以上变化略高于您。

在一般情况下,如果元值是任意的,那么所介绍的问题就称为:Knapsack Problem,并且已知属于NP-complete(

采用x 1-2 = 51, xl = 50, x[0] = 1, X = 100。 然后,该算法必须考虑以硬币x2进行变革的可能性,或者从x. 开始作出改变。 The first-ped with national methage, otherwise known as Greedy Algorithm——to wit,“使用的最大硬币少于工作总量”,将不使用病理。 反之,这种算法经历了一种合并的爆炸,使其变成了国家机器。

对于某些特殊硬币价值安排,例如几乎所有实际用途,包括虚构的X[i+1]=2x[i],甚至给出的虚构案例中的O(1)算法非常快,可以确定最佳产出。 这些算法利用了硬币价值的特性。

我不知道有动态的方案拟订办法:一种是利用方案规划模拟所要求的最佳分解决办法。 一般来说,只有能将问题分解成次要问题,才能通过动态的方案拟订解决问题,而这种问题在最佳解决时,可以重新纳入一个可以证明是最佳的解决办法。 也就是说,如果方案管理员不能在数学上证明(“prove”)重新确定问题的最佳分解决办法会导致最佳解决办法,那么就不能适用动态的方案。

经常举出的动态方案拟订的一个例子是采用多种矩阵。 根据矩阵的大小,选择评价A<>>>>。 B。 C (A,,>B,,/b>)或(A,(B,C)>)等两种对应形式之一,即:(,,>B,>>>,,>,,>>,>或(,>,,>,>;,>,>>,>(,,>,>>,>>>>>>>>>>>>。 也就是说,一种方法比另一种方法更为优化(法斯特)。 动态方案规划是一种模拟,它降低了不同方法的计算成本,并按照计算时间(或program)的计算时间表(或program)进行了实际计算。

一个关键特征是,计算是根据计算时间表进行的,而不是列举所有可能的组合,即计算是否是重复进行的。 举例来说,在每一步骤中,只选择了成本最低的重复。 因此,从不计算中间成本次最佳时间表的可能费用。 换言之,该时间表并不是通过寻找最佳时间表来计算,而是从零开始逐步建立最佳时间表。

术语动态方案规划可以与线性方案拟订相比较,在这种方案拟订中,方案也按时间表的含义使用。

为更多地了解动态方案规划,查阅关于我所知算法的最大书,,“Introduction to Algorithms”,作者是Cormen、Leserson、Rivest和Stein/a。 “最大”是“RSA”的R,动态方案拟订只是核心的一个章节。

Cover of the recommended book.

i 如果你以复读方式写,那是罚款,只是以记忆为基础的搜索。 你们必须储存你计算出的东西,否则不会再计算。

int memory[#(coins)]; //initialize it to be -1, which means hasn t been calculated
MakeChange(X, x[1..n this is the coins], i){
    if(memory[i]!=-1) return memory[i];
    for (int i = 1; i < n; i++)
    {
        if ( (X - x[i] ==0) || MakeChange(X - x[i], i) ){
            memory[i]=true;
            return true;
        }
    }
    return false;
}




相关问题
How to add/merge several Big O s into one

If I have an algorithm which is comprised of (let s say) three sub-algorithms, all with different O() characteristics, e.g.: algorithm A: O(n) algorithm B: O(log(n)) algorithm C: O(n log(n)) How do ...

Grokking Timsort

There s a (relatively) new sort on the block called Timsort. It s been used as Python s list.sort, and is now going to be the new Array.sort in Java 7. There s some documentation and a tiny Wikipedia ...

Manually implementing high performance algorithms in .NET

As a learning experience I recently tried implementing Quicksort with 3 way partitioning in C#. Apart from needing to add an extra range check on the left/right variables before the recursive call, ...

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

Enumerating All Minimal Directed Cycles Of A Directed Graph

I have a directed graph and my problem is to enumerate all the minimal (cycles that cannot be constructed as the union of other cycles) directed cycles of this graph. This is different from what the ...

Quick padding of a string in Delphi

I was trying to speed up a certain routine in an application, and my profiler, AQTime, identified one method in particular as a bottleneck. The method has been with us for years, and is part of a "...