码迷,mamicode.com
首页 > 其他好文 > 详细

USACO Humble Numbers

时间:2017-11-16 22:05:15      阅读:201      评论:0      收藏:0      [点我收藏+]

标签:mes   ret   接下来   小根堆   main   soft   mem   mic   最小   

USACO 

Humble Numbers

    这题主要是两种做法,第一种是比较常(jian)规(dan)的-------------用pq(priority_queue)维护,每次取堆中最小值(小根堆),用这个值松(mei)弛(ju)

  一遍所有的素数,大概是O(n*k*logn)的,所以--------闭眼睛T啊!!

    冷静一下,我们来看第二种做法:

  显然,在第一种做法中,我们重复计算了堆中的好多值,而这些我们可以通过记录一个地址来优化。

  我们假设已经求出了前i个丑数,对于第(i+1)个丑数,我们可以枚举所有的素数并且记录这个素数已经枚举到了哪个丑数,这样我们在接下来的求解过

  就不会重复那些当前地址之前的所有丑数。

    附上想丑数一样丑陋的代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
ll a[110];
int dis[110];
ll ugly[100100];
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    a[0]=1;
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
    }
    sort(a+1,a+n+1);
    ugly[0]=1;
    memset(dis,0,sizeof(dis));
    int minn;
    for(int i=1;i<=m;i++)
    {
        minn=n;//记录哪一个值恰好满足条件
        for(int j=1;j<=n;j++)
        {
            if(a[j]*ugly[dis[j]]>ugly[i-1]&&a[j]*ugly[dis[j]]<a[minn]*ugly[dis[minn]])
                minn=j;
        }
        ugly[i]=a[minn]*ugly[dis[minn]];//更新满足条件者
        dis[minn]++;//更新满足条件者
        for(int j=1;j<=n;j++)
        {
            while(a[j]*ugly[dis[j]]<ugly[i]) dis[j]++;
            if(a[j]*ugly[dis[j]]==ugly[i]) dis[j]++;
        }
    }
    printf("%lld",ugly[m]);
    return 0;
}

  小结:本题所得到的想法及错误。

      1.没更新主值(ugly);

      2.35行是重要的,因为如果这个素数的地址并没有满足要求,那么它在下一次美剧

  

USACO Humble Numbers

标签:mes   ret   接下来   小根堆   main   soft   mem   mic   最小   

原文地址:http://www.cnblogs.com/ShuraK/p/7846412.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!