题目描述:
饭店的大师傅老蔡正准备炒菜,而徒弟小刚正在和几个服务员微信聊天和抢红包,老蔡发现炒菜没油了,高喊小刚去储藏室里倒油,小刚走进储藏室看到有 n 个油桶都装满了油,这 n 个油桶容积 (整数) 大小各不相同,小刚需要 m 升 (整数) 油,请你不借助任何其他容器,能否直接从 n 桶油中任意取 k 桶 (1<=k<=n) 油,其油的总量正好时 m 升,如果可以就输出 “yes”,否则输出 “no”
输入描述
多组输入第一行两个整数 n,m。第二行 n 个整数,即油桶的容积。n,m 均不超过 100,每个油桶容积不超过 100。
输出描述
一行 yes 或 no
样例输入:
5 10
1 2 3 1 1
6 11
3 5 3 2 1 4
样例输出:
no
yes
代码如下
#include<bits/stdc++.h>
using namespace std;
//回溯法
/*
5 10
1 2 3 1 1
6 11
3 5 3 2 1 4
*/
int needOil;//需要的油的数量
int PailNum;//油桶的数量
int* a;
bool* select;
bool FindFlag = 0;
bool JudgeOver(int node,int rv) {
int sum = 0;
for (int i = node; i < PailNum; i++)
{
sum += a[i];
}
if (sum < rv)
{
return 0;
}
else
{
return 1;
}
}
void DFS( int V , int*a,int node) {
if (FindFlag==1)
{
return;
}
// V 代表现在已经储存的油量
if (V== needOil)
{
cout << "yes" << endl;
FindFlag = 1;
return;
}
if (JudgeOver(node, needOil - V) == 0)//如果下面的 算上本次的不可能超过V就退出
{
cout << "no" << endl;
FindFlag = 1;
return;
}
else
{
//如果不会超过需要的就进行左分支。
if (V + a[node] <= needOil)
{
V += a[node];
select[node] = true;
DFS(V, a, node + 1);
select[node] = false;
V -= a[node];
}
else
{
cout << "no" << endl;
FindFlag = 1;
return;
}
//如果不会 太少进行右分支
if (JudgeOver(node+1, needOil - V) == 0)//如果下面的 不算上本次的不可能超过V就退出
{
cout << "no" << endl;
FindFlag = 1;
return;
}
else
{
select[node] = false;
DFS(V, a, node + 1);
select[node] = false;
}
}
}
int main() {
while (cin>> PailNum>> needOil)
{
a = new int[PailNum];
for (int i = 0; i < PailNum; i++)
{
cin >> a[i];
}
select = new bool[PailNum]; memset(select, false, PailNum * sizeof(bool));
FindFlag = 0;
//初始容量为0;从第一个开始遍历
DFS(0, a,0);
}
return 0;
}