蒜头君去书店买书,他有m元钱,书店里面有n本书,每本书的价格为pi 元。蒜头君很爱学习,想把身上钱都用来买书,并且刚好买k本书。请帮蒜头君计算他是否能刚好用m元买k本书。
输入格式
第一行输入3个整数 m(1≤m≤100000000),n(1≤n≤30),k(1≤k≤min(8,n))
接下来一行输入n个整数,表示每本书的价格 pi(1≤pi≤100000000)。
输出格式
如果蒜头君能刚好用m元买k本书,输入一行"Yes", 否则输出"No"。
样例输入1
10 4 4
1 2 3 4
样例输出1
Yes
样例输入2
10 4 3
1 2 3 4
样例输出2
No
解题思路:枚举每一本书买或者不买,我们用dfs来抽象枚举的过程,我们在搜索的过程中,用s记录当前买的书的总价钱,用x记录选择书的本书,在第一层dfs时,先枚举是否买第一本书,如果买则k+1,s加上这本书的价钱,进入下一层;如果不买,直接进入下一层,以后每一层都这么处理。
#include <iostream>
using namespace std;
int n,m,k,ans=0;
int p[35];
/*t表示搜索树第t层(从0开始),x表示买了x本书,s表示当前买的书总价钱*/
void dfs(int t,int x,int s){
if(x==k){
if(s==m){
ans=1;
return ;
}else{
return ;
}
}
if(t>n) return;
dfs(t+1,x,s);/*没有买第t本书*/
dfs(t+1,x+1,s+p[t]);/*买了第t本书*/
return;
}
int main(){
cin>>m>>n>>k;
for(int i=0;i<n;i++)
cin>>p[i];
dfs(0,0,0);
if(ans){
cout<<"Yes"<<endl;
}else{
cout<<"No"<<endl;
}
return 0;
}