題目鏈接:
http://acm.nyist.net/JudgeOnline/problem.php?pid=1058
描述
給定整數a1、a2、…….an,判斷是否可以從中選出若干數,使它們的和恰好爲K。
輸入
首先,n和k,n表示數的個數,k表示數的和。
接着一行n個數。
(1<=n<=20,保證不超int範圍)
輸出
如果和恰好可以爲k,輸出“YES”,並按輸入順序依次輸出是由哪幾個數的和組成,否則“NO”
樣例輸入
4 13 1 2 4 7 |
樣例輸出
YES 2 4 7 |
算法思想:
這道題要求如果和恰好可以爲k時,輸出“YES”,且並按輸入順序依次輸出是由哪幾個數的和組成,故不能使用別的貪心算法之類的。
這是一道簡單的深度搜索,給定的數要麼取,要麼不取,直接深度搜索就可以遍歷所有的情況。(每次提交都完了加#include 頭文件,沒誰了。。。)
源代碼
/*
Authoer:楊林峯
Date:2017.10.14
NYOJ(1058):部分和問題
*/
#include <iostream>
#include <cstring>
using namespace std;
int n, k, a[25], vis[25], ko;
/*深度搜索*/
void DFS(int i, int s)
{
//退出條件
if (ko) return;
if (s == k)
{
ko = 1;
cout << "YES" << endl;
for (int i = 0; i < 25; i++)
{
if (vis[i])
cout << a[i] << " ";
}
cout << endl;
return;
}
if (s > k) return;
if (i >= n)return;
int tmp = s; //記憶上次s值
vis[i] = 1; //取當前數,更新s和vis[]記錄數組
s += a[i];
DFS(i + 1,s);
vis[i] = 0; //不取當前數,更新s和vis[]記錄數組
s = tmp; //不取當前數,需回溯
DFS(i + 1, s);
}
int main()
{
while (cin >> n >> k)
{
memset(a, 0, sizeof(a));
memset(vis, 0, sizeof(vis));
ko = 0;
for (int i = 0; i < n; i++)
cin >> a[i];
DFS(0, 0);
if (ko == 0)
cout << "NO" << endl;
}
return 0;
}