部分和问题

题目来源

挑战程序设计竞赛(第二版)

语言

C/C++

题目

部分和问题

描述

给定整数 a1, a2, ..., an,判断是否可以从中选出若干数,使它们的和恰好为 k。

样例1

输入:

n = 4

a = {1, 2, 4, 7};

k = 13

输出:

Yes

样例2

输入:

n = 4

a = {1, 2, 4, 7};

k = 15

输出:

No

思路

这道题目可以分解成两步,第一步先选取若干数,第二步对这些数进行求和判断是否等于 k。

以样例 1 为例,输入 4 个数,选取其中的若干数,求和,判断其和是否为 13。从头对这 4 个数进行依次访问,既然要选取若干数,那么每个数都有被选中或者弃选的可能(2 种情况),可以将整个选数的情况看做一棵二叉树,从根结点到叶子结点的路径就成为一组选数的可能。

(该图前两个数的情况)

只需要对这棵树进行遍历,每次遍历到叶子结点时判断一下当前的 sum 是否与 13 相等,若相等为找到一组数据,不相等继续遍历,若这棵树从头遍历一遍没有出现想要的结果,则判定无结果。

 

对这棵树进行遍历,我们可以使用深度优先搜索(DFS)。

代码

#include <iostream>
#define MAXBUF 256

int n = 4;
int k = 13;
int a[MAXBUF] = {1, 2, 4, 7}; 

bool dfs(int i, int sum);

int main(int argc, char *argv[]) {
	using namespace std;
	
	if (dfs(0, 0)){
		cout << "Yes";
	} 
	else
		cout << "No";
	
	return 0;
}

// i 为第 i 个数据 a[i-1],sum 为当前部分和 
bool dfs(int i, int sum)
{
	if (i == n){	// DFS 停止条件 
		return sum == k;
	} 
	if (dfs(i + 1, sum)){	// 下个数据不加 
		return true;
	}
	if (dfs(i + 1, sum + a[i])){	// 下个数据加 
		return true;
	} 
	
	return false;	// 遍历所有结果都无符合条件 
} 

时间复杂度

对 n 个数进行遍历,每个数都有 2 种情况,因此时间复杂度为 O(2^n)。

所涉及的知识点

深度优先搜索(DFS)

 

 

 

 

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值