如何在C中找到子集和中的所有子集(使用动态规划)

如何在C中找到子集和中的所有子集(使用动态规划),c,sum,subset,C,Sum,Subset,我是C语言的新手(学习了1.5个月),我们的大学教授要求我们找到子集和问题的动态规划解决方案(以及其他两个),但我按照他的指示做了,我被困在如何实际找到(打印)所需的子集上。有人能帮我理解这是如何工作的,以及如何找到所有的子集吗 对于下面的代码,表是{3,2,1,2,4,3,4,1},子集的总和需要达到7 编辑!-->我修改了初始代码,以便找出存在多少个子集,这些子集和特定的值相加(在我们的示例7中,子集是20)。我重复一遍,我需要帮助找到所有的子集(组合),它们的总和为一个值(在本例中为7)

我是C语言的新手(学习了1.5个月),我们的大学教授要求我们找到子集和问题的动态规划解决方案(以及其他两个),但我按照他的指示做了,我被困在如何实际找到(打印)所需的子集上。有人能帮我理解这是如何工作的,以及如何找到所有的子集吗

对于下面的代码,表是{3,2,1,2,4,3,4,1},子集的总和需要达到7

编辑!-->我修改了初始代码,以便找出存在多少个子集,这些子集和特定的值相加(在我们的示例7中,子集是20)。我重复一遍,我需要帮助找到所有的子集(组合),它们的总和为一个值(在本例中为7)

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

子集1:3 2 1
子集2:32
子集3:3 1 2 1
子集4:3 1 3
子集5:34
子集6:3 1
子集7:34
子集8:2114
子集9:2 1 3 1
子集10:2 1 4
子集11:23
子集12:2 4 1
子集13:2 4 1
子集14:1 2 4
子集15:1231
子集16:1 2 4
子集17:2 4 1
子集18:2 4 1
子集19:43
子集20:3 4

在下面的C代码中,我能够打印出指令所要求的表格,通过这个表格我必须找到所有的子集。该表的说明如下:

x[i][j]=x[i-1][j];
如果(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]);
}
#包括
#包括
内部主(空)
{
长集[]={3,2,1,2,4,3,4,1};
长和=7;
长n=sizeof(set)/sizeof(set[0]);
iter子集和(集合,n,和);
返回0;
}
int iter_子集_和(int*y,长n,长和){
int i,j,k,**x;
x=malloc((n+1)*sizeof(long**));
对于(i=0;i
#包括
int iscan(int a[],int n,int sum){
int f[sum+1],m=0,i,j,k,el,o=0;
对于(i=1;isum?和:m+el;
对于(k=m-el,j=m;k>=0;j--,k--){
if(f[k]){
/*f[j]=el;*///仅旧的最后一个conest
将_推到_堆栈的数组_(在j位置,项目大小为el);//此伪代码提示您的作业************所以在构建连接的_堆栈数组_后更改打印所有组合
}
}
如果(!f[sum])继续;
k=总和;
while(k){
printf(“%d”,f[k]);
k-=f[k];
}
printf(“%s\n”和“);
//出口(0);
o++;
}
//printf(“%s\n”、“不能”);
返回o;
}
int main(){
int set[]={1,3,2,4,2,6,5};
整数和=5;
返回iscan(set,sizeof(set)/sizeof(set[0]),sum;
}

非常感谢您的快速回答!但是我检查了您的代码,它没有正确打印所有子集+如果可能的话,我想要一个用c语言编写的代码,用我上面提到的方法查找所有子集。您可以尝试更改我的代码(只需在数组中添加堆栈),以便将“跳跃”净额从总和添加到0吗?并添加完整的打印输出所有组合。
#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);
}