• HDU 6125 Free from square 状态压缩DP + 分组背包


    Free from square

    Problem Description
    There is a set including all positive integers that are not more then n. HazelFan wants to choose some integers from this set, satisfying: 1. The number of integers chosen is at least 1 and at most k. 2. The product of integers chosen is 'free from square', which means it is divisible by no square number other than 1. Now please tell him how many ways are there to choose integers, module 10^9+7.
     
    Input
    The first line contains a positive integer T(1T5), denoting the number of test cases.
    For each test case:
    A single line contains two positive integers n,k(1n,k500).
     
    Output
    For each test case:
    A single line contains a nonnegative integer, denoting the answer.
     
    Sample Input
    2 4 2 6 4
     
    Sample Output
    6 19
     
    题解:
      n个数
      首先你明白,1~n个数,没有数是包含超过两个 大于根号n 的质因子的,
      小于根号n的质因子只有8个,所以做这个题的思路就有了
      对于只含有小于根号n的 那些质因子的那些数,我们状态压缩DP就好了
      对于包含大于根号n 的 那些质因子的 那些数,我们分组背包, 也就是说 某些包含同一个 大于根号n的 因子 放在一组里边
    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define ls i<<1
    #define rs ls | 1
    #define mid ((ll+rr)>>1)
    #define pii pair<int,int>
    #define MP make_pair
    typedef long long LL;
    typedef unsigned long long ULL;
    const long long INF = 1e18+1LL;
    const double pi = acos(-1.0);
    const int N = 5e2+20, M = 1e3+20,inf = 2e9,mod = 1e9+7;
    
    int p[] = {2,3,5,7,11,13,17,19};
    vector<int > fi,se[N];
    int dp[2][N][(1<<8)+10],f[N];
    
    int solve(int n,int K) {
        fi.clear();
        memset(dp,0,sizeof(dp));
        for(int i = 0; i <= n; ++i) se[i].clear(),f[i] = 0;
        fi.push_back(1);
        for(int i = 2; i <= n; ++i) {
            int tmp = i,now = 0,ok = 1;
            for(int j = 0; j < 8; ++j) {
                int _ = 0;
                while(tmp % p[j] == 0) _++,now|=(1<<j),tmp/=p[j];
                if(_ >= 2) ok = 0;
            }
            if(ok) {
                f[i] = now;
                if(tmp!=1) se[tmp].push_back(i);
                else fi.push_back(i);
            }
        }
        int now = 0;
        dp[0][0][0] = 1;
        for(int i = 0; i < fi.size(); ++i) {
    
            now ^= 1;memset(dp[now],0,sizeof(dp[now]));
            for(int k = 0; k <= K; ++k) {
                for(int j = 0; j < (1<<8); ++j) {
    
                    dp[now][k][j] += dp[now^1][k][j];
                    dp[now][k][j] %= mod;
    
                    if((j&f[fi[i]])) continue;
    
                    dp[now][k+1][j|f[fi[i]]] += dp[now^1][k][j];
                    dp[now][k+1][j|f[fi[i]]] %= mod;
    
                }
            }
        }
    
        for(int i = 1; i <= n; ++i) {
            if(se[i].size() == 0) continue;
         //   cout<<"shit"<<endl;
            now^=1;memset(dp[now],0,sizeof(dp[now]));
            for(int h = 0; h <= K; ++h) {
               for(int k = 0; k < (1<<8); ++k) {
    
                   dp[now][h][k] += dp[now^1][h][k];
                      dp[now][h][k] %= mod;
    
                    for(int j = 0; j < se[i].size(); ++j) {
                      if((f[se[i][j]]&k)) continue;
                      dp[now][h+1][f[se[i][j]]|k] += dp[now^1][h][k];
                      dp[now][h+1][f[se[i][j]]|k] %= mod;
                    }
                }
            }
        }
    
        int ans = 0;
        for(int i = 1; i <= K; ++i) {
            for(int j = 0; j < (1<<8); ++j)
                ans += dp[now][i][j],ans %= mod;
        }
        return ans;
    }
    
    
    int main() {
        int T,n,k;
        scanf("%d",&T);
        while(T--) {
            scanf("%d%d",&n,&k);
            printf("%d
    ",solve(n,k));
        }
        return 0;
    }
    /*
    2
    4 2
    6 4
    */
  • 相关阅读:
    python-多任务-进程
    注解_Annotation
    ZIP压缩输入/输出流
    什么是API,这篇文章让你豁然开朗
    异常处理(在控制台输入数据)
    控件监听与面板监听
    多态与继承
    Java——socketser与cli
    20170307
    20180305
  • 原文地址:https://www.cnblogs.com/zxhl/p/7383875.html
Copyright © 2020-2023  润新知