P2723 丑数 Humble Numbers

  我还真没想出来……不要怪我哦……

  我想的是一直往堆里塞数,知道数的个数超多n很多。

  首先,这个超过很多很难把控,其次,复杂度不允许。

  于是我们考虑一波dp:

  f [ i ] 表示第i个丑数,那么这个丑数 f [ i ] 一定等于 f [ k ] * a [ j ] (其中 k < i )。

  那么我们对于每一个 i ,我们枚举 k 和 j ,找到大于 f [ i - 1 ] 的最小的数即为 f [ i ] 。

  但是这是 n2 * k 的,对于1e5……我们还得考虑优化。

  再考虑一波:

  假设 f [ i ] = f [ k ] * a [ j ] 

  假设 f [ i + 1 ] =f [ t ] * a [ j ] 

  那么 t 一定大于 k,所以对于每一个 j ,我们都维护现在的k是多少,每一次都从 k + 1 开始找。

  这样复杂度就变成了 n * k + k * n (好理解),即 n * k 。

  以及,long long……

  代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
#define maxn 400005
#define int long long
#define inf 99999999999999
int p[maxn],f[maxn],s[maxn];
main()
{
    int k,n;
    scanf("%lld%lld",&k,&n);
    for(int i=1;i<=k;i++)
        scanf("%lld",&p[i]);
    f[0]=1;
    for(int i=1;i<=n;i++)
    {
        int MIN=inf;
        for(int j=1;j<=k;j++)
        {
            while(f[i-1]>=f[s[j]]*p[j]) s[j]++;
            MIN=min(MIN,f[s[j]]*p[j]);
        }
        f[i]=MIN;
    }
    printf("%lld\n",f[n]);
    return 0;
}
 

猜你喜欢

转载自www.cnblogs.com/popo-black-cat/p/10994240.html