Algorithm 从给定集合中找出所有方法求和给定数(允许重复)

Algorithm 从给定集合中找出所有方法求和给定数(允许重复),algorithm,Algorithm,给定一个由n个元素组成的数组(例如[1,2])和一个数字“k”(例如6),找出所有可能的方法来生成sum=k 举个例子,答案是4,因为 1 1 1 1 1 1 1 1 1 1 2 1 1 2 2 2 2 2 我能想到的算法是用蛮力,我们模拟所有可能的场景,当给定的状态无法达到结果时停止 arr[] = [1,2] k = 6 globalCount =0; function findSum(arr,k) { if(k ==0) glob

给定一个由n个元素组成的数组(例如[1,2])和一个数字“k”(例如6),找出所有可能的方法来生成sum=k

举个例子,答案是4,因为

1 1 1 1 1 1
1 1 1 1 2
1 1 2 2
2 2 2
我能想到的算法是用蛮力,我们模拟所有可能的场景,当给定的状态无法达到结果时停止

 arr[] = [1,2]
    k = 6
   globalCount =0;
   function findSum(arr,k)
   {
      if(k ==0)
         globalCount++
         return
      else if(k<0)
         return

      for each i in arr{
       arr.erase(i)
       tmp = k
       findSum(arr,tmp)
       while(k>=0){
          findSum(arr,tmp -= i)
      } 
   }
arr[]=[1,2]
k=6
全球账户=0;
函数findSum(arr,k)
{
如果(k==0)
全球账户++
返回
else如果(k=0){
findSum(arr,tmp-=i)
} 
}
我不确定我的解决方案是否是最有效的。请评论/更正或显示指向更好解决方案的指针

编辑:如果有人能告诉我我的代码及其soln代码的运行时复杂性,我将不胜感激。:)
我认为我的代码复杂度是Big-O(n^w)w=k/avg(arr[0]…arr[n-1])

这是分区问题的一个有趣子集。如果允许所有整数,实际上有一个封闭形式的解决方案(请参见和)

搜索“受限配分函数”给了我一些线索。对这个问题的两个解决方案进行了非常严格的数学讨论


不幸的是,我太懒了,无法编写这些代码。它们是非常密集的解决方案。

如果你愿意原谅那些花哨的linq技巧,你可能会发现这个C#解决方案很有用。幸运的是,林克读起来有点像英语。我们的想法是建立解决方案,因为
k
从0开始递增,直到它达到正确的值。
k
的每个值都基于以前的解决方案。不过,你必须注意的一件事是,确保你找到的新“方式”不是对他人的重新排序。我解决这个问题的办法是,如果它们被分类,就把它们算作有效的。(这只是一个比较)

它使用动态规划方法,应该比简单的递归方法更快。我想。我知道它的速度足够快,可以在几毫秒内计算出打破一美元的方法的数量。(242)

静态void填充subsetsum(int[]a,int K,int runSum,int idx,ArrayList ans,ArrayList al){
如果(idx>=a.length | | runSum>K)
返回;
if(runSum==K){
ans.add(新ArrayList(al));
返回;
}
ArrayList temp=新的ArrayList(al);
临时添加(a[idx]);
populateSubsetSum(a,K,runSum+a[idx],idx,ans,temp);//当允许元素的重复时
填充subsetsum(a、K、runSum、idx+1、ans、al);
}
将此函数称为:

populateSubsetSum(a,K,0,0,ans,new ArrayList<>());//array,sum,initial_sum,global 2d list,temp list
populateSubsetSum(a,K,0,0,ans,new ArrayList())//数组、总和、初始总和、全局2d列表、临时列表

代码的+1可能重复。天哪!如果你不告诉我,我永远都不会知道这是一个编译和执行的程序。这很像英语你能发布它的C或Python版本吗?感谢Queequeg发现问题背后的问题。:)
1 1 1 1 1 1
1 1 1 1 2
1 1 2 2
2 2 2
 static void populateSubsetSum(int[]a,int K,int runSum,int idx,ArrayList<ArrayList<Integer>> ans,ArrayList<Integer> al){
    if(idx>=a.length || runSum>K)
        return;
    if(runSum==K){
        ans.add(new ArrayList<>(al));
        return;
    }
    ArrayList<Integer> temp=new ArrayList<>(al);
    temp.add(a[idx]);
    populateSubsetSum(a,K,runSum+a[idx],idx,ans,temp);//when repitions of elements are allowed
    populateSubsetSum(a,K,runSum,idx+1,ans,al);
}
populateSubsetSum(a,K,0,0,ans,new ArrayList<>());//array,sum,initial_sum,global 2d list,temp list