题目分析
给出一组序列a1…an 让你找出另外一组序列b1…bm使得序列a中能够表示的所有数序列b同样能够表示出来。让你求出序列b最小需要多少个元素。
首先分析一个性质:bi一定属于序列a中元素
反证法:假设bi不属于序列a,bi可以被序列a中元素表示出来,然而序列a中元素又可以通过序列b表示出来,那么bi可以被自己所在的序列b表示出来,则bi一定不属于序列b (序列b一定最简),所以bi一定属于序列a
序列b中元素一定不能相互表示
那么我们只需要在序列a中找到不能够被其他元素表示的ai就可以的出序列b
利用完全背包求出每个数字j能够被表示的方案数,最后统计方案数为1的j即为b序列中元素。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=2e5+10;
int n,m,ans;
ll f[maxn];
int a[maxn];
int main() {
int T;
cin>>T;
while(T--) {
cin>>n;
for(int i=1; i<=n; i++) {
cin>>a[i];
m=max(m,a[i]);
}
memset(f,0,sizeof(f));
f[0]=1;
for(int i=1; i<=n; i++) {//完全背包求方案数
for(int j=a[i]; j<=m; j++) {
f[j]+=f[j-a[i]];//f(i,j)=f(i-1,j)+f(i,j-a[i]);
}
}
ans=0;
for(int i=1;i<=n;i++){//统计那些数字不能被其他数字表示
if(f[a[i]]==1)ans++;
}
cout<<ans<<endl;
}
return 0;
}