先导入一张图片,现在还是原始社会,未学latex语法,过完年再学!
以上集合并集的求解就是容斥原理了,对于该题目,使用了二进制,非常的精妙
代码:
m>>1表示m的二进制数向右移动一位。例如:m=4,m>>1=2,m>>1=1,m>>1=0
1<<m表示以m为指数以2为底的数,例如m=4,1<<m=16
问题:对于本题目可以使用dfs的做法,但我现在还不会
时间复杂度:共有2^m项,每项时间复杂度为m所以 O(2^m*m)
#include<iostream>
using namespace std;
typedef long long ll;
const int N=20;
int p[N];
int main(){
int m;
int n;
cin>>n>>m;
int res=0;
for(int i=0;i<m;i++)cin>>p[i];
for(int i=1;i<(1<<m);i++){
int cnt=0;//集合出现的次数
int t=1;//初始集合的乘积
for(int j=0;j<m;j++){
if(i>>j&1){
if((ll)t*p[j]>n){
t=-1;
break;
}
t=t*p[j];
cnt++;
}
}
//if(t==-1)continue;
if(t!=-1){
if(cnt%2)res=res+n/t;//(cnt&1)
else
res=res-n/t;
}
}
cout<<res;
return 0;
}