zoukankan      html  css  js  c++  java
  • 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
    */
  • 相关阅读:
    去除ArrayList中重复自定义对象元素
    ArrayList去除集合中字符串的重复值(字符串的内容相同)
    java-前端之css
    java-前端之HTML
    java-JDBC
    java-JDBC
    Oracle-视图,约束
    Oracle-查询,,..
    Oracle-查询
    Oracle-查询之函数
  • 原文地址:https://www.cnblogs.com/zxhl/p/7383875.html
Copyright © 2011-2022 走看看