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; }