现在的位置: 首页 > 综合 > 正文

USACO / Humble Numbers(较难DP)

2013年10月14日 ⁄ 综合 ⁄ 共 1531字 ⁄ 字号 评论关闭

Humble Numbers

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

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

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 printedalone on a line.

SAMPLE OUTPUT (file humble.out)

27

 

我只能说,这道题技巧性太强了…

我竟然SB地从1开始一个数一个数的判断是不是humble number。。。这不是找超时么。。。

看了官方的思路才做出来的


官方题解 

我们在数组hum中计算出前n个丑数。为了实现起来更简单,我们把1也作为一个丑数,算法也要因此略微调整一下。

当我们已知前k个丑数,想得到第k+1个,我们可以这样做:

对于每个质数p 寻找最小的丑数h 使得h * p 比上一个丑数大

取我们找到的 h * p 中最小的一个:它就是下一个丑数 为了使搜索更快,我们可以为每个质数维护一个索引“pre[i]”表示每i个质数已经乘到了哪个丑数,每次都从那里开始,而不是再从头再来。

 

 /*
ID:138_3531
LANG:C++
TASK:humble
*/

#include <iostream>
#include <fstream>
#include <cmath>
#include <cstring>
using namespace std;

ifstream fin("humble.in");
ofstream fout("humble.out");
int n,k;
int a[101];
int h[100005];
int pre[101];
void input()
{
    fin>>k>>n;
    for (int i=0;i<k;i++)
    {
        fin>>a[i];
    }
}
int main()
{
    input();
    h[0]=1;
    for (int i=1;i<=n;i++)
    {
        int minn=0x7FFFFFFF;
        for (int j=0;j<k;j++)
            for (int p=pre[j];p<i;p++)
                if (h[p]*a[j]>h[i-1])
                {
                    if (h[p]*a[j]<minn)
                        minn=h[p]*a[j];
                    pre[j]=p;
                    break;
                }

        h[i]=minn;
    }
    fout<<h[n]<<endl;
    return 0;
}

抱歉!评论已关闭.