二刷提高课,题解目录在这里— 提高课的题解目录
当看到这道题时我们可能就会认为b是在无穷个数中选择m个,我们会无从下手
但当我们观察后可以知道题目要求等价,若能表示出则均可以表示出否则不能表示出
性质一:这就意味所选择的b一定可以表示出a中所有的数
通过样例我们可以知道,当一个数字可以被其他数线性表示,则这个数可以去掉
那么我们选择的b可以选择a之外的数吗?
倘若我们选择了a之外的数,分析一下所面临的的情况
情况1:这个数无法被a表示出,这就导致了我们所构造出的系统无法等价,不满足条件
情况2:可以被a内的数字表示出,根据上面可以知道当被线性表示时可以去掉
所以我们可以知道性质二:b所选择的数字一定在a中
由上文我们又可以确定性质三:b内任何数均不能被其他数字选择
根据这三个性质,我们可以确定一定是在a内进行枚举
倘若a内一个数可以被其他a内的数表示,根据三可以知道不可选
如果一个a不能被其他数字选取,则一定要选
这就确定了我们的选择方案,也就是枚举a选择a中不可以被其他a表示的数字
如何确定枚举顺序能使得尽少的重复呢?
我们排序在进行遍历即可
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=110,M=25010;
int a[N],f[M];
int res;
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
memset(f,0,sizeof f);
f[0]=1;
res=0;
sort(a+1,a+1+n);
for(int i=1;i<=n;i++)
{
if(!f[a[i]])res++;
for(int j=a[i];j<=a[n];j++)
{
f[j]|=f[j-a[i]];
}
}
cout<<res<<endl;
}
return 0;
}