任务
给出一个由N个元素组成的数组,通过选择数组中的某些元素(或没有元素)并将它们相加来检查是否有可能获得S的和。
使用位集
#include<bits/stdc++.h>
using namespace std;
bitset<1000000+10> bit;
int a[100];
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
}
int s;
cin>>s;
bit[0]=1;
for(int i=0;i<n;i++){
bit|=bit<<a[i];
}
if(bit[s]){
cout<<"YES"<<endl;
}
else{
cout<<"NO"<<endl;
}
}
使用位掩码
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;cin>>t;
while(t--){
int n; cin>>n; int a[n+5];
for(int i=0;i<n;i++) cin>>a[i];
int s,i,j; cin>>s;
for(i=0;i<(1<<n);i++){
int x=0;
for(j=0;j<n;j++){
if(i & (1<<j)) x+=a[j];
}
if(x==s){
cout<<"YES\n"; break;
}
}
if(i==(1<<n)) {cout<<"NO\n";}
}
return 0;
}
但是我知道这里的时间复杂度可以清楚地看出O(2 ^ n * n)
1)但是当我们谈论位集时,它可能看起来像O(n * max(a [i])) 我说这是因为,如果我们考虑将位集中的位移位为O(n) 那么对于数组元素的最大值,我们可能必须将位集中的10 ^ 6位移位 (不确定按位操作的时间复杂度)
2)但是另一方面,位掩码不能在数组中使用超过64个数字,我们可以在位集中存储10 ^ 6个数字(不确定位集的范围)
如果我在以上两个陈述中有误,请更正。
从这里可以得出结论,位集比位掩码更有效?