• hdu6125 Free from square 分组背包+状态压缩


    /**
    题目:hdu6125 Free from square
    链接:http://acm.hdu.edu.cn/showproblem.php?pid=6125
    题意:
    从不大于n的所有正整数中选出至少1个且至多k个使得乘积不包含平方因子,对10^9+7取模。
    1≤n,k≤500。
    思路:
    分组背包+状态压缩
    把n个数分成若干组,互斥的放在同一组。
    
    一开始把所有含平方因子的数去除掉,剩下的进行分组。
    
    <sqrt(500)的八个素因子,编成八组,分别为包含2,3,5,7,11,13,17,19素因子的数。 注意包含的数不能重复。
    >sqrt(500)的素因子,每一组为包含该素因子的数。
    1这个数为一组.
    
    因为其他组可能包含2,3,5,7,11,13,17,19;也就是这八个素因子在其他组也可能出现。
    
    为了判断用状态压缩处理。
    
    dp[k][s]表示选k个,前8个素因子选择状态为s时候的方法数。
    
    dp[k][s] += dp[k-1][s-s1]; (s&s1==s1)
    
    memset(dp, 0, sizeof dp);
    dp[0][0] = 1;
    
    ans = sigma[1<=i<=m]sigma[0<=s<(1<<8)]dp[i][s];
    */
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <set>
    #include <iostream>
    #include <cmath>
    #include <vector>
    #include <map>
    using namespace std;
    typedef long long LL;
    #define ms(x,y) memset(x,y,sizeof x)
    typedef pair<int, int> P;
    const int inf = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    const int maxn = 501;
    int prime[maxn], tot;
    int pos[20];
    vector<P> v[maxn];
    int vis[maxn];
    LL dp[maxn][1<<8];
    void init()
    {
        for(int i = 2; i < maxn; i++){
            if(prime[i]==0){
                for(int j = i*2; j < maxn; j+=i){
                    prime[j] = 1;
                }
            }
        }
        tot = 0;
        for(int i = 2; i < maxn; i++){
            if(prime[i]==0){
                prime[++tot] = i;
            }
        }
        for(int i = 1; i <= 8; i++){
            pos[prime[i]] = i-1;
        }
        for(int i = 2; i < maxn; i++){
            int x = i;
            for(int j = 1; j <= tot&&prime[j]<=tot; j++){
                int cnt = 0;
                if(x%prime[j]==0){
                    while(x%prime[j]==0){
                        x/=prime[j];
                        cnt++;
                    }
                    if(cnt>1){
                        vis[i] = 1; break;
                    }
                }
            }
        }
        v[0].push_back(P(1,0));///表示1这个数。
        for(int i = 9; i <= tot; i++){
            for(int j = prime[i]; j < maxn; j+=prime[i]){
                if(vis[j]) continue;
                int s = 0;
                for(int k = 1; k <= 8; k++){
                    if(j%prime[k]==0){
                        s |= (1<<pos[prime[k]]);
                    }
                }
                v[i].push_back(P(j,s));
                vis[j] = 1;
            }
        }
        for(int i = 1; i <= 8; i++){
            for(int j = prime[i]; j < maxn; j+=prime[i]){
                if(vis[j]) continue;
                int s = 0;
                for(int k = 1; k <= 8; k++){
                    if(j%prime[k]==0){
                        s |= (1<<pos[prime[k]]);
                    }
                }
                v[i].push_back(P(j,s));
                vis[j] = 1;
            }
        }
    
    }
    LL solve(int n,int m)
    {
        ms(dp,0);
        dp[0][0] = 1;
        int len = 1<<8;
        for(int i = 0; i <= tot; i++){
            if(prime[i]>n) break;
            for(int j = m; j >= 1; j--){
                for(int k = 0; k < (int)v[i].size(); k++){
                    if(v[i][k].first>n) continue;
                    for(int s = 0; s < len; s++){
                        if((s&v[i][k].second)==v[i][k].second){
                            dp[j][s] = (dp[j][s]+dp[j-1][s-v[i][k].second])%mod;
                        }
                    }
                }
            }
        }
        LL ans = 0;
        for(int i = 1; i <= m; i++)
            for(int s = 0; s < len; s++)
                ans = (ans+dp[i][s]) %mod;
        return ans;
    }
    int main()
    {
        init();
        int T;
        int n, k;
        cin>>T;
        while(T--)
        {
            scanf("%d%d",&n,&k);
            printf("%lld
    ",solve(n,k));
        }
    
        return 0;
    }
  • 相关阅读:
    iOS常用的终端指令
    instancesRespondToSelector与respondsToSelector的区别
    Struts2(一)快速入门
    pl/sql快速输入select * from等语句快捷键设置
    win10系统安装oracle11g时遇到INS-13001环境不满足最低要求
    JSP四大作用域
    J2EE开发模式
    JAVA四大域对象总结
    Apache与Tomcat有什么关系和区别
    Junit测试框架
  • 原文地址:https://www.cnblogs.com/xiaochaoqun/p/7389196.html
Copyright © 2020-2023  润新知