【主要内容】

回顾旧知识 回溯法(子集和,数独)

学习新知识 动态规划(数字三角形,矩阵连乘,石子合并)

 

子集和

【题目描述】

子集和问题的一个实例为<S,c>。其中S={x1,x2,…,xn}是一个正整数的集合,c是一个正整数。子集和问题判定是否存在S的一个子集S1,使得S1中所有元素的和为c。 试设计一个解子集和问题的回溯法。

【样例输入】

5 10 2 2 6 5 4

【样例输出】

2 2 6

【题解】

如同回溯法解决01背包问题一样,这里子集和,问题等价为背包容量为10,如下有2,2,6,5,4五个物品,价值和重量都一样 。不过还是利用0代表不取,1代表取其物品。

构建搜索二叉树,每一层都是一个物品,左子树是取,右子树是不取,当走到某一叶子结点时该结点的价值之和为10时,说明有一组解

 

 1 #include<cstdio>
 2  3 const int N = 30 ;
 4 int vis[N] ;
 5 int a[N] ;
 6 int n , k ;
 7 bool flag = false ;
 8 void dfs( int step , int sum ){
 9     if( sum == k ){
10         for( int i = 1 ; i <= n ; i++ )
11             if( vis[i] ) printf("%d ",a[i]);
12         putchar('\n');
13         flag = true ;
14         return ;
15     }
16     if( step == n + 1 ) return ;
17     if( sum + a[step] <= k ){
18         vis[step] = 1 ;
19         dfs( step + 1 , sum + a[step] );
20         vis[step] = 0 ;
21     }
22     dfs( step + 1 , sum );
23 }
24 int main()
25 {
26     scanf("%d%d",&n,&k);
27     for( int i = 1 ; i <= n ; i++ ){
28         scanf("%d",&a[i]);
29     }
30     dfs( 1 , 0 );
31     if( !flag ){
32         printf("-1\n");
33     }
34     return 0 ;
35 }
子集和问题

相关文章:

  • 2022-01-07
  • 2021-09-13
  • 2021-06-28
  • 2021-07-04
  • 2021-07-11
  • 2021-08-13
  • 2022-12-23
  • 2021-08-15
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-01-08
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案