码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 1796 How many integers can you find(容斥原理+二进制/dfs)

时间:2015-08-18 01:21:19      阅读:118      评论:0      收藏:0      [点我收藏+]

标签:acm   算法   数论   dfs   

How many integers can you find

Time Limit: 12000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 5556    Accepted Submission(s): 1593


Problem Description
  Now you get a number N, and a M-integers set, you should find out how many integers which are small than N, that they can divided exactly by any integers in the set. For example, N=12, and M-integer set is {2,3}, so there is another set {2,3,4,6,8,9,10}, all the integers of the set can be divided exactly by 2 or 3. As a result, you just output the number 7.
 

Input
  There are a lot of cases. For each case, the first line contains two integers N and M. The follow line contains the M integers, and all of them are different from each other. 0<N<2^31,0<M<=10, and the M integer are non-negative and won’t exceed 20.
 

Output
  For each case, output the number.
 

Sample Input
12 2 2 3
 

Sample Output
7
 


题目大意:

求n以内能够被所给的集合中的数整除的数的个数。

解题思路:
这里要运用我们所说的容斥原理。所谓容斥原理,运用起来要记住“奇加偶减”。
比如求100以内能被2,3,11,13,41整除的数的个数,我们即u(i)为100以内能被i整除的数的个数。

那么答案就是:

u(2)+u(3)+u(11)+u(13)+u(41)
-u(2*3)-u(3*11)-u(11*13)-u(13*41)
+u(2*3*11)+u(3*11*13)+u(11*13*41)
-u(2*3*11*13)-u(3*11*13*41)
+u(2*3*11*13*41)
这就是所谓的“奇加偶减”。
同时n以内能被i整除的数的个数为(n-1)/i。
综上,我们就可以通过枚举集合中的数,再容斥来得到答案。
枚举有2中方法:暴力枚举和dfs。由于m最大只有10,暴力枚举时我们可以使用二进制来代表某个状态,每一位代表去与不取。dfs就很简单了。


参考代码:

/*
二进制
Memory: 1568 KB		Time: 639 MS
Language: G++		Result: Accepted
*/
#include<map>
#include<stack>
#include<queue>
#include<cmath>
#include<vector>
#include<cctype>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const double eps=1e-10;
const int INF=0x3f3f3f3f;
const int MAXN=25;
typedef long long LL;

int n,m,num[MAXN],divi[MAXN];

int gcd(int a,int b)
{
    return b?gcd(b,a%b):a;
}

int lcm(int a,int b)
{
    return a/gcd(a,b)*b;
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif // ONLINE_JUDGE
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        int cnt=0;
        for(int i=0;i<m;i++)
        {
            scanf("%d",&num[i]);
            if(num[i])
                divi[cnt++]=num[i];
        }
        m=cnt;
        int ans=0;
        for(int k=1;k<(1<<m);k++)
        {
            int select=0,tlcm=1;
            for(int i=0;i<m;i++)
            {
                if(k&(1<<i))
                {
                    select++;
                    tlcm=lcm(tlcm,divi[i]);
                }
            }
            if(select&1)
                ans+=(n-1)/tlcm;
            else
                ans-=(n-1)/tlcm;
        }
        printf("%d\n",ans);
    }
    return 0;
}

/*
dfs
Memory: 1572 KB		Time: 109 MS
Language: G++		Result: Accepted
*/
#include<map>
#include<stack>
#include<queue>
#include<cmath>
#include<vector>
#include<cctype>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const double eps=1e-10;
const int INF=0x3f3f3f3f;
const int MAXN=25;
typedef long long LL;

int n,m,num[MAXN],divi[MAXN],ans;

int gcd(int a,int b)
{
    return b?gcd(b,a%b):a;
}

int lcm(int a,int b)
{
    return a/gcd(a,b)*b;
}

void dfs(int pos,int tlcm,int select)
{
    //if(pos>m)     
    //    return ;
    tlcm=lcm(tlcm,divi[pos]);
    select++;
    if(select&1)
        ans+=(n-1)/tlcm;
    else
        ans-=(n-1)/tlcm;
    for(int i=pos+1;i<m;i++)
        dfs(i,tlcm,select);
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif // ONLINE_JUDGE
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        int cnt=0;
        for(int i=0; i<m; i++)
        {
            scanf("%d",&num[i]);
            if(num[i])
                divi[cnt++]=num[i];
        }
        m=cnt;
        ans=0;
        for(int i=0;i<m;i++)
            dfs(i,1,0);
        printf("%d\n",ans);
    }
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

HDU 1796 How many integers can you find(容斥原理+二进制/dfs)

标签:acm   算法   数论   dfs   

原文地址:http://blog.csdn.net/noooooorth/article/details/47735797

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!