• USACO / Humble Numbers(较难DP)


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

  • 相关阅读:
    HDU4366 Successor 线段树+预处理
    POJ2823 Sliding Window 单调队列
    HDU寻找最大值 递推求连续区间
    UVA846 Steps 二分查找
    HDU3415 Max Sum of MaxKsubsequence 单调队列
    HDU时间挑战 树状数组
    UVA10168 Summation of Four Primes 哥德巴赫猜想
    UESTC我要长高 DP优化
    HDUChess 递推
    HDU4362 Dragon Ball DP+优化
  • 原文地址:https://www.cnblogs.com/AbandonZHANG/p/2598277.html
Copyright © 2020-2023  润新知