Problem:Baby Coins
Description:
Baby 今天清点自己的百宝箱啦,箱子里有 n 种硬币,硬币的面值分别是:val[1],val[2],…,val[n],每种面值的硬币都恰好有 2 个。Baby 实在闲的太无聊了,他想从他所拥有的硬币中选出若干个,使得面值之和为 k。那么他的目标能否实现呢 ~
Input:
每一组数据第一行都包含两个数字 n(n≤18),k(1≤k≤109)。n 代表箱子中所包含的硬币种数,k 代表 Baby 需要组成的金钱数额。接下来的一行代表 val[1],val[2],…,val[n]。(1≤val[i]≤ 107)
Output:
如果Baby能组成金钱数额k,请输出Yes,否则输出No。
Sample Input:
2
2 10
3 4
3 9
1 2 10
Sample Output:
Case 1: Yes
Case 2: No
Language:C++
#include <iostream>
#include <set>
using namespace std;
int n,k;
int val[20];
set<int>st1,st2;
void dfs(int left,int right,int sum,set<int>&st)
{
if(left==right)
{
st.insert(sum);
return;
}
dfs(left+1,right,sum,st);
dfs(left+1,right,sum+val[left],st);
dfs(left+1,right,sum+2*val[left],st);
}
bool check()
{
for(set<int> ::iterator it=st1.begin();it!=st1.end();it++)
{
if(st2.find(k-*it)==st2.end()) continue;
return true;
}
return false;
}
int main()
{
int T;
cin>>T;
int num=1;
while(T--)
{
cin>>n>>k;
for(int i=0;i<n;i++) cin>>val[i];
bool flag=false;
if(n==1)
{
if(val[0]==k||2*val[0]==k) flag=true;
}
else
{
dfs(0,n/2,0,st1);
dfs(n/2,n,0,st2);
flag=check();
}
cout<<"Case "<<num++<<": "<<(flag ? "Yes":"No")<<endl;
st1.clear();
st2.clear();
}
return 0;
}