Humble Numbers

For a given set of K prime numbers S = {p1, p2, ..., pK}, consider the set of all numbers whose prime factors are a subset of S. This set contains, for example, p1, p1p2, p1p1, and p1p2p3 (among others). This is the set of `humble numbers' for the input set S. Note: The number 1 is explicitly declared not to be a humble number.

Your job is to find the Nth humble number for a given set S. Long integers (signed 32-bit) will be adequate for all solutions.

PROGRAM NAME: humble

INPUT FORMAT

Line 1: Two space separated integers: K and N, 1 <= K <=100 and 1 <= N <= 100,000.
Line 2: K space separated positive integers that comprise the set S.

SAMPLE INPUT (file humble.in)

4 19
2 3 5 7

OUTPUT FORMAT

The Nth humble number from set S printed alone on a line.

SAMPLE OUTPUT (file humble.out)

27

题的叙述非常简单,但是需要一定的方法,若是一个一个的枚举当然是会T的,我们应该采取一些优化的方法。
不难发现第N个丑数能够由第N-1个丑数求的,可以由那K个元素与之前的N-1个丑数的乘积选出一个大于第K-1个丑数并且最小。
假设第K个丑数:Ck=Ni*Fj(1<=i<=N,1<=j<=k)那么Ck+1>Ck=Ni*Fj,所以对于第i个元素,只需要查询j之后的丑数。
可以得出如下代码:

for(int i=1;i<=k;i++){
int ans=hhh;
int l;
for(int j=1;j<=n;j++){
while(dp[last[j]]*a[j]<=dp[i-1])last[j]++;
if(ans>dp[last[j]]*a[j]){
ans=dp[last[j]]*a[j];
}
}
dp[i]=ans;
}

 

完整代码:

/*
ID: yizeng21
PROB: humble
LANG: C++
*/
#include<iostream>
#include<stdio.h>
#define hhh (1<<30)-1+(1<<30)
using namespace std;
long long a[100000],dp[100000];
int last[100000];
int min(int i,int j){
    return i<j?i:j;
}
int main(){
    freopen("humble.in","r",stdin);
    freopen("humble.out","w",stdout);
    long long n,k;
    cin>>n>>k;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    dp[0]=1;
    for(int i=1;i<=k;i++){
        int ans=hhh;
        int l;
        for(int j=1;j<=n;j++){
            while(dp[last[j]]*a[j]<=dp[i-1])last[j]++;
            if(ans>dp[last[j]]*a[j]){
                ans=dp[last[j]]*a[j];
            }
        }
        dp[i]=ans;
    }
    cout<<dp[k]<<endl;
}