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
    */
  • 相关阅读:
    libTIFF 图像读取与保存
    MarkDown写作之嵌入LaTeX和HTML
    R语言学习(一)前言
    Multi-Byte Character Set & Unicode Character Set
    C/C++ ShellExecuteEx调用exe可执行文件
    C/C++中相对路径与绝对路径以及斜杠与反斜杠的区别
    观察者模式
    责任链模式
    桥接模式
    void及void指针含义的深刻解析
  • 原文地址:https://www.cnblogs.com/zxhl/p/7383875.html
Copyright © 2011-2022 走看看