部分和问题
来源:互联网 发布:新闻文章网站源码 编辑:程序博客网 时间:2024/05/16 06:00
最近重操旧业开始攻基本的算法~第一个算法:部分和问题,语言,C++
问题描述:给定整数a1,a2,a3....an,判断是否可以选出若干个数,使他们的和恰好为K。
输入:n=4,a={1,2,4,7}.k=13
输出: yes (13=2+4+7)
原理:使用递归解决,类似于剪枝,只要该方向的sum值加起来比k大,就立刻弃掉该分支,如果小,则继续伸枝。
源代码:
#include <iostream>
#include <vector>
#include <string>
#include <cstdlib>
using namespace std;
vector<int> a;
int k;
int flag = 0;
void function(int index, int sum, vector<int> record)
{
if (index == a.size())
{
if (sum != k)
return ;
}
if (sum > k)
{
return;
}
if (sum<k)
{
record[index] = 1;
function(index + 1, sum + a[index],record);
record[index] = 0;
function(index+1,sum,record);
}
if (sum == k)
{
if (flag == 0) //只打印一个yes
{
cout << "yes";
flag = 1;
}
vector<int> tmp;
for (int i = 0; i < record.size();i++)
{
if (record[i] == 1)
tmp.push_back(a[i]);
}
cout << " ("<<k<<"=";
for (int i = 0; i < tmp.size(); i++)
{
if (i == tmp.size() - 1)
cout << tmp[i];
else
cout << tmp[i] << "+";
}
cout << ")";
return;
}
}
int main(void)
{
int n;
cout << "n=";
cin >> n;
getchar();
for (int i = 0; i < n; i++)
{
int tmp;
cin >> tmp;
a.push_back(tmp);
getchar();
}
cin >> k;
vector<int> record = a; //record用来记录该值是否被加入
for (int i = 0; i < record.size(); i++)
record[i] = 0;
//对于每一个元素,都只有两种情况,取还是不取(当然这里考虑的是不能重复)将复杂的问题简单化
function(0, 0,record);
if (flag == 0)
cout << "NO" << endl;
return 0;
}
#include <vector>
#include <string>
#include <cstdlib>
using namespace std;
vector<int> a;
int k;
int flag = 0;
void function(int index, int sum, vector<int> record)
{
if (index == a.size())
{
if (sum != k)
return ;
}
if (sum > k)
{
return;
}
if (sum<k)
{
record[index] = 1;
function(index + 1, sum + a[index],record);
record[index] = 0;
function(index+1,sum,record);
}
if (sum == k)
{
if (flag == 0) //只打印一个yes
{
cout << "yes";
flag = 1;
}
vector<int> tmp;
for (int i = 0; i < record.size();i++)
{
if (record[i] == 1)
tmp.push_back(a[i]);
}
cout << " ("<<k<<"=";
for (int i = 0; i < tmp.size(); i++)
{
if (i == tmp.size() - 1)
cout << tmp[i];
else
cout << tmp[i] << "+";
}
cout << ")";
return;
}
}
int main(void)
{
int n;
cout << "n=";
cin >> n;
getchar();
for (int i = 0; i < n; i++)
{
int tmp;
cin >> tmp;
a.push_back(tmp);
getchar();
}
cin >> k;
vector<int> record = a; //record用来记录该值是否被加入
for (int i = 0; i < record.size(); i++)
record[i] = 0;
//对于每一个元素,都只有两种情况,取还是不取(当然这里考虑的是不能重复)将复杂的问题简单化
function(0, 0,record);
if (flag == 0)
cout << "NO" << endl;
return 0;
}
效果:
可以解决多种答案情况,分析一下,对每个值都进行了取与不取的选择,时间效率个跟内存使用情况都比较大,不是很理想。
以下还有一种代码比较少的:
bool dfs(int index,int sum)
{
if (i==n) return sum==k;
if(dfs(index+1,sum)) return true; //加上当前值的情况
if(dfs(index+1,sum+a[index])) return true; //不加上当前index的情况
return false; //如果前面都没有返回则返回false
}
这种比较简单,代码量少,时间空间的使用是一样的,这种也是提供了一种思路,用机器的思维去解决任务。
0 0
- DFS 部分和问题
- 部分和问题
- 多重部分和问题
- 部分和问题
- 部分和问题
- 部分和问题
- nyoj 部分和问题
- nyoj-部分和问题
- nyoj1058部分和问题
- 部分和问题
- nyoj 部分和问题
- 部分和问题
- 部分和问题
- 部分和问题
- 多重部分和问题
- 部分和问题
- 部分和问题
- 部分和问题
- (六)Qt内存管理
- 【Leetcode】235. Lowest Common Ancestor of a Binary Search Tree
- POJ 1961Period(KMP算法)
- HTML5本地存储——IndexedDB(一:基本使用)
- Catch That Cow POJ - 3278
- 部分和问题
- 1023. 组个最小数 (20)
- C++概述(一)
- python爬虫入门(一)
- ios 生成IPA文件
- noip2016练习题(2.区间)
- 机器学习笔记 - 性能度量
- 基础练习 高精度加法
- weka学习[1]_Eclipse中读取arff文件