【问题标题】:How to find all subsets in Subset Sum (with Dynamic Programming) in C如何在 C 中找到子集总和(使用动态编程)中的所有子集
【发布时间】:2017-03-21 13:07:51
【问题描述】:

我是 C 的新手(学习 1.5 个月),我们的大学教授要求我们找到子集和问题的动态编程解决方案(以及其他 2 个),但我已按照他的指示进行,并且我'我坚持如何实际找到(打印)请求的子集。有人可以帮我理解这是如何工作的以及如何找到所有子集吗?

对于下面的代码,表格是{3,2,1,2,4,3,4,1},子集需要相加为7。

编辑! --> 我修改了初始代码,以便找出有多少子集总和为特定值(在我们的例子中是 7,子集是 20)。我再说一遍,我需要帮助来查找总和为一个值(在本例中为 7)的所有子集(组合)。

在上述情况下,这意味着代码将能够打印 20 个子集,它们是:

子集 1:3 2 1 1
子集 2:3 2 2
子集 3:3 1 2 1
子集 4:3 1 3
子集 5:3 4
子集 6:3 3 1
子集 7:3 4
子集 8:2 1 4
子集 9:2 1 3 1
子集 10:2 1 4
子集 11:2 2 3
子集 12:2 4 1
子集 13:2 4 1
子集 14:1 2 4
子集 15:1 2 3 1
子集 16:1 2 4
子集 17:2 4 1
子集 18:2 4 1
子集 19: 4 3
子集 20:3 4

在下面的 C 代码中,我可以打印指令要我打印的表格,并且通过这个表格我必须找到所有子集。该表的说明是:

x[i][j]=x[i-1][j]; if(j>=y[i-1]) x[i][j]+=x[i-1][j-y[i-1]];

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
long set[] = {3,2,1,2,4,3,4,1};
long sum =7;
long n = sizeof(set)/sizeof(set[0]);
iter_subset_sum(set, n, sum);
return 0;
}

int iter_subset_sum (int *y, long n, long sum) {
  int i,j,k,**x;
  x=malloc((n+1)*sizeof(long**));
  for(i=0;i<=n;i++)
    x[i]=malloc((sum+1)*sizeof(long*));

  for (i=0; i<=n; i++)
    x[i][0] = 1;    
  for (i=1; i<=sum; i++)
    x[0][i] =0;
  for (i=1; i<=n; i++) {    
    for (j=1; j<=sum; j++){
    x[i][j]=x[i-1][j];
    if(j>=y[i-1])
        x[i][j]+=x[i-1][j-y[i-1]];  }   }
  for (i = 0; i <= n; i++){
        for (j = 0; j <= sum; j++)
          printf ("%4d", x[i][j]);
              printf("\n");
      }
      printf("There are %d subsets :", x[n][sum]);
}

提前非常感谢您!如果你能帮助像我这样想慢慢“深入”C语言的新手,我将不胜感激......

【问题讨论】:

    标签: c sum subset


    【解决方案1】:
    #include <stdio.h>
    int iscan(int a[],int n,int sum){
        int f[sum+1],m=0,i,j,k,el,o=0;
        for(i=1;i<=sum;i++)f[i]=0;f[0]=1;
        for(i=0;i<n;i++){
            el=a[i];
            if(el>sum)continue;
            m=m+el>sum?sum:m+el;
            for(k=m-el,j=m;k>=0;j--,k--){
                if(f[k]){
                    /* f[j]=el;*/ //old only last conest
                                push_toarray_of_stack(on j position ,item size of el);;//this pseudocode is hint for u homework*********** so and change printing all combination after builing array_of_stack's  of conection
    
                }
            }
            if(!f[sum])continue;
            k=sum;
            while(k){
                printf("%d ",f[k]);
                k-=f[k];
            }
            printf("%s\n","");
            //exit(0); 
                o++;
        }
        //printf("%s\n","can't");
        return o;
    }
    
    int main(){
      int set[] = {1, 3, 2, 4, 2, 6, 5};
      int sum = 5;
      return iscan(set,sizeof(set)/sizeof(set[0]),sum);
    }
    

    【讨论】:

    • 非常感谢您的快速回答!但是我检查了你的代码,它没有正确打印所有子集+如果可能的话,我想要一个 c 中的代码,它可以按照我上面提到的方式找到所有子集..
    • 您可以尝试更改我的代码(只需在数组中添加堆栈),这样您就可以得到从 sum 到 0 的“跳跃”净值?并添加完整的打印输出所有组合。
    猜你喜欢
    • 1970-01-01
    • 2021-12-28
    • 1970-01-01
    • 2013-08-20
    • 1970-01-01
    • 1970-01-01
    • 2013-09-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多