LC最近沉迷于一个游戏,每天玩的很欢乐。但是这个游戏有一个不好的地方,就是当你要买一个道具时,你必须要从你现有的各种面值的金币中凑齐这个道具的钱,不能多也不能少,否则你就购买不了这个道具。现在LC想买一个新道具,但是最近LC忙于学习,没时间计算自己是否买得了这个道具,所以请你来帮他计算一下。
输入格式:
第一行输入样例组数t(1<=t<=20)。 每组数据输入两个正整数n(1<=n<=10)和m(1<=m<=10
7
),代表有现在有n个金币和想买的道具的价格m。接下来一行输入n个正整数,为每个金币的面值,可能有相同的,范围在[1,2∗10
6
]内。
输出格式:
每组数据,在一行中输出"YES",若现有的金币能够组成想买的道具的价格;否则输出"NO"(不包含双引号)。
输入样例:
2
3 3
1 1 1
5 16
1 2 3 4 5
输出样例:
YES
NO
提示
10%的数据,1<=n<=5,1<=m<=10
20%的数据,1<=n<=5,1<=m<=25
40%的数据,1<=n<=10,1<=m<=10
3
60%的数据,1<=n<=10,1<=m<=10
5
100%的数据,1<=n<=10,1<=m<=10
7
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,m,end,sign=-1;
scanf("%d%d",&n,&m);
int s[n];
for(int g=0;g<n;g++)
scanf("%d",&s[g]);
for(int i=0;i<(1<<n);i++)//例如题中n=3时,i<8,即i从0-7递增,将其转为二进制表示,列举出三个纸币的所有使用情况,000表示三个纸币一个都不选,1表示选,0不选
{ end=0;//可以理解为是所拥有纸币的全部花法
for(int f=0;f<n;f++)
if(i&(1<<f))end+=s[f];//当判断式不为零时,表示选用此种纸币,用循环来看每种纸币的使用情况
{printf("YES\n");
sign=100;
break;} }
if(sign==-1)printf("NO\n");}
return 0;
}
笔记
这道题用到了二进制枚举的思想,可以实现从一堆数据中,多次无规则选取,直到符合条件。
本题无特殊函数,重在思维