Java coin算法的复杂性

Java coin算法的复杂性,java,algorithm,big-o,complexity-theory,Java,Algorithm,Big O,Complexity Theory,有人能告诉我这段代码的复杂性(最好是大O符号)吗?它找到了达到目标金额所需的最少数量的“硬币”。 为此,它计算从1开始到目标的每个数字的最小硬币数。每个数字都是根据可能的数字对求和而得出的,并使用成本最小的数字对。希望通过一个例子来说明这一点 如果“硬币”是{1,3,4},目标是13,那么它从1迭代到13,其中2的代价是(0+2,1+1)的最小值,c(5)是(c(0)+c(5),c(1)+c(4),c(2)+c(3))等的最小代价,直到c(13) 这是背包问题的一个版本,我想知道如何定义它的复杂

有人能告诉我这段代码的复杂性(最好是大O符号)吗?它找到了达到目标金额所需的最少数量的“硬币”。 为此,它计算从1开始到目标的每个数字的最小硬币数。每个数字都是根据可能的数字对求和而得出的,并使用成本最小的数字对。希望通过一个例子来说明这一点

如果“硬币”是{1,3,4},目标是13,那么它从1迭代到13,其中2的代价是(0+2,1+1)的最小值,c(5)是(c(0)+c(5),c(1)+c(4),c(2)+c(3))等的最小代价,直到c(13)

这是背包问题的一个版本,我想知道如何定义它的复杂性

代码:

import java.util.*;
公共类货币{
公共静态最终整数目标=12003;
公共静态int[]validCoins={1,3,5,6,7,10,12};
公共静态void main(字符串[]args){
Arrays.sort(validCoins);
麻袋();
}
公共静态void sack(){
地图硬币=新的树形地图();
硬币。投入(0,0);
int a=0;

例如(int i=1;i我认为你提供的代码有点混乱。因此,这篇文章更多地是关于概念算法而不是实际算法。这可能有点不同,因为例如,在
ArrayList
中插入不是O(1),但我相信你可以使用良好的数据结构(例如
LinkedList
s)为此,需要让所有操作在固定时间内运行

您的算法的基本功能如下:

  • 它从一个地图开始,将所有给定的硬币映射到一个:需要一个硬币才能实现硬币上的价值
  • 对于每个迭代,它将所有已实现的值与所有已实现的值混合。因此,结果是硬币的总和,并取硬币数量的总和,除非它已经存在于集合中
  • 这一步你忘记了:踢出比要求值严格大的值:因为所有硬币都是严格正的,你将永远无法构造这样一个组合小于要求值的值
  • 您一直这样做,直到您构建了所需的硬币价值
  • 如果在迭代i时,添加到集合中的所有值都严格大于所请求的值,则可以停止:无法构造所请求的值
  • 参数包括:

    • n:硬币的数量
    • r:请求的值
    第一个观察结果是(2.)的每一步都需要O(s^2)时间,s是迭代开始时集合中的元素数:这是因为您将每个值与每个值匹配

    第二个观察结果是,集合中的元素不可能超过请求的值。这意味着s以O(r)为界(我们假设所有硬币都是整数,因此集合最多可以包含从0到r-1的所有整数值)。因此,步骤(2.)的最大时间复杂度为O(r^2)

    此外,集合会逐步演化:在每次迭代中,您总是构造一个新值,该值至少比迄今为止的最大值大一个。因此,算法将执行最大O(r)迭代

    这意味着该算法的时间复杂度为O(r^3):r乘以O(r^2)


    为什么行为是指数的,因此至少是NP难的

    第一个论点是,它涉及到如何表示输入:在许多情况下,数字是使用基数大于或等于
    2
    的系统表示的。这意味着对于k个字符,可以表示一个以O(g^k)为刻度的值以g为基数。因此是指数的。换句话说,如果你使用一个
    32
    -位的数字,最坏的情况是,r=O(2^32)因此,如果你把它作为输入,有一个指数部分。如果你用一元符号对目标进行编码,算法是P。但当然这有点像padding参数:如果你提供了足够多的无用输入数据(指数或甚至超指数),所有算法都是P,但你不会买太多

    第二个参数是,如果您将请求的值从输入中保留,则只能声明从n个硬币开始。您知道迭代次数是固定的:您将目标值视为未知常量。每次迭代,映射中的值总数都可能是平方的。这意味着国家努力是:

    n+n^2+n^4+n^6+...n^(log r)
    ^  ^                    ^
    |  \-- first iteration  \-- end of algorithm
    \-- insertion
    

    很明显,这种行为在n中是指数型的。

    我搜索过类似的问题,但找不到任何带有大O符号的问题,在wiki页面上,它简单地说,使用动态编程,它是psuedo多项式。此外,我知道问题取决于目标和硬币,因此它不仅仅是nWell伪多项式仍然是NP完全的,因此硬币的数量是指数的,但仅限于要组合的查询数字的多项式。但由于数字通常表示为基数大于或等于2的数字,因此它可以按位数的指数缩放。@CommuSoft我不太明白,比方说我有k个硬币,其和为m,复杂性为与O(m^ k)有关吗?不,它是具有L参数的O(m^ l),但r=o(r^ k)具有r a参数。为什么不使用更简单的DP方法,而不是考虑所有对,我们只考虑k个选项(即V [i]=min [C:C1,…CK](V[i-C])+ 1。这将产生O(k*n)算法。
    n+n^2+n^4+n^6+...n^(log r)
    ^  ^                    ^
    |  \-- first iteration  \-- end of algorithm
    \-- insertion