[usaco]丑数

思考

首先产生的思路是,用小根堆的最小元素(top)来与 k个数 相乘,之后把结果再扔进小根堆,每次操作得到的即是第k小。 不过要注意一下判重。但是非常悲剧的是 在遇到极限数据的时候TLE了。在思索无果的情况下,偷偷去看了发题解。发现题目的解法还是比较巧妙的。

#include <queue>
#include <cstdio>
#include <iostream>
#define LL long long
using namespace std;
LL num[105],ans[100005],cnt;
struct node{
    LL x;
    bool operator < (const node A)const{
    return x>A.x;
    }
    node(LL x){
        this->x=x;
    }
};
priority_queue<node>s;

int main(){
    LL k,n,i;
    scanf("%lld%lld",&k,&n);
    for(register int i=1;i<=k;i++){
        scanf("%lld",&num[i]);
    }
    s.push(node(1));
    while(cnt<=n){
        LL x = s.top().x;
        s.pop();
        if(ans[cnt]<x){
            ans[++cnt]=x;
            for(register int i=1;i<=k;i++) s.push(node(num[i]*x));
        }
    }
    printf("%lld",ans[n+1]);
}

这里附上82分的TLE代码

题解的思路是什么呢? f[i]表示第i小  那么f[i]一定大于f[i-1] 我们要做的是 f[i]大于f[i-1] 并尽量的小(读者:这不是废话吗?)

其次 f[i]一定是这k个数中的某个数 乘 f[i-1]或者f[i-2]或者f[i-3]....得来的,那么思路就出来了。  但是这三层循环还是有可能TLE。所以要进一步优化.

很容易发现满足条件的丑数x*a[j]>f[i-1],一定满足条件,x*a[j]>f[i-2];于是我们就可以从满足x*a[j]>f[i-2]的丑数x的位置往后枚举,找到满足条件x*a[j]>f[i-1]的丑数。

然后和min比较。

#include <cstdio>
#include <iostream>
typedef unsigned long long ll;
using namespace std;
const int maxn=100011;
ll Num[123],f[maxn],jl[maxn];
ll n,MIN,k;
int main(){
    scanf("%lld%lld",&k,&n);
    for(int i=1;i<=k;i++) scanf("%lld",&Num[i]);
    f[0]=1;
    for(int i=1;i<=n;i++){
        MIN=3e9;
        for(int j=1;j<=k;j++){
            //为什么要jl[j]++ 因为如果不加的话 到f[i+1] f[jk[j]]*Num[j] 一定也是<=f[i]
            //其次 s[j]存的是a[j]至少与第几小丑数相乘才能得到一个比f[i-1]大的丑数
            while(Num[j]*f[jl[j]]<=f[i-1]) jl[j]++;
            MIN = min(MIN,Num[j]*f[jl[j]]);
        }
        f[i] = MIN;
    }
    printf("%lld",f[n]);
}
时间: 2024-12-29 01:58:32

[usaco]丑数的相关文章

插入排序的优化【不靠谱地讲可以优化到O(nlogn)】 USACO 丑数

首先我们先介绍一下普通的插排,就是我们现在一般写的那种,效率是O(n^2)的. 普通的插排基于的思想就是找位置,然后插入进去,其他在它后面的元素全部后移,下面是普通插排的代码: 1 #include<iostream> 2 #include<fstream> 3 #include<stdio.h> 4 using namespace std; 5 int a[200000]; 6 int p[200000]; 7 8 int main(){ 9 ios::sync_wi

USACO 3.1 丑数

题目:https://www.luogu.org/problemnew/show/P2723 强烈谴责quq:这题根本不是黄题!! 根据题意,若令丑数集合为f,目前在第i个丑数,我们要判断f[i]的值 由于现在的丑数都是由另一个丑数乘以个数得来(我们假设f[0] = 1),利用类似dp的思想,我们知道f[i] = min(f[t] * a[j]),其中f[t]表示之前的丑数,j for 1 - k: 找到最小的值即可 直接这么做是O(n^2k)的,凉的很彻底orz 考虑优化:由于f是递增的,因此

洛谷P2723 丑数 Humble Numbers [2017年 6月计划 数论07]

P2723 丑数 Humble Numbers 题目背景 对于一给定的素数集合 S = {p1, p2, ..., pK},考虑一个正整数集合,该集合中任一元素的质因数全部属于S.这个正整数集合包括,p1.p1*p2.p1*p1.p1*p2*p3...(还有其 它).该集合被称为S集合的“丑数集合”.注意:我们认为1不是一个丑数. 题目描述 你的工作是对于输入的集合S去寻找“丑数集合”中的第N个“丑数”.所有答案可以用longint(32位整数)存储. 补充:丑数集合中每个数从小到大排列,每个丑

AC日记——丑数 codevs 1246

1246 丑数 USACO 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description 对于一给定的素数集合 S = {p1, p2, ..., pK}, 来考虑那些质因数全部属于S 的数的集合.这个集合包括,p1, p1p2, p1p1, 和 p1p2p3 (还有其它).这是个对于一个输入的S的丑数集合.注意:我们不认为1 是一个丑数.你的工作是对于输入的集合S去寻找集合中的第N个丑数.longint(signe

洛谷P2723 丑数 Humble Numbers

P2723 丑数 Humble Numbers 52通过 138提交 题目提供者该用户不存在 标签USACO 难度普及/提高- 提交  讨论  题解 最新讨论 暂时没有讨论 题目背景 对于一给定的素数集合 S = {p1, p2, ..., pK},考虑一个正整数集合,该集合中任一元素的质因数全部属于S.这个正整数集合包括,p1.p1*p2.p1*p1.p1*p2*p3...(还有其它).该集合被称为S集合的“丑数集合”.注意:我们认为1不是一个丑数. 题目描述 你的工作是对于输入的集合S去寻找

1246 丑数

1246 丑数 USACO 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description 对于一给定的素数集合 S = {p1, p2, ..., pK}, 来考虑那些质因数全部属于S 的数的集合.这个集合包括,p1, p1p2, p1p1, 和 p1p2p3 (还有其它).这是个对于一个输入的S的丑数集合.注意:我们不认为1 是一个丑数.你的工作是对于输入的集合S去寻找集合中的第N个丑数.longint(signe

Humble Numbers(丑数) 超详解!

给定一个素数集合 S = { p[1],p[2],...,p[k] },大于 1 且素因子都属于 S 的数我们成为丑数(Humble Numbers or Ugly Numbers),记第 n 大的丑数为 h[n]. 算法 1: 一种最容易想到的方法当然就是从 2 开始一个一个的判断一个数是否为丑数.这种方法的复杂度约为 O( k * h[n]),铁定超时(如果你这样做而没有超时,请跟 tenshi 联系) 算法 2: 看来只有一个一个地主动生成丑数了 : 我最早做这题的时候,用的是一种比较烂的

lintcode 中等题:Ugly Numbers 丑数

题目 丑数 设计一个算法,找出只含素因子3,5,7 的第 k 大的数. 符合条件的数如:3,5,7,9,15...... 样例 如果k=4, 返回 9 挑战 要求时间复杂度为O(nlogn)或者O(n) 解题 法一:直接暴力,逐次判断一个数是不是丑数 下面只对其中的奇数判断是否是丑数,加不加奇数都超时. class Solution { /** * @param k: The number k. * @return: The kth prime number as description. */

34 - 丑数

题目描述:http://ac.jobdu.com/problem.php?pid=1214 把只包含因子2.3和5的数称作丑数(Ugly Number).例如6.8都是丑数,但14不是,因为它包含因子7. 习惯上我们把1当做是第一个丑数.求按从小到大的顺序的第N个丑数. 解析: 丑数的定义应该为:质因子只含有2.3.5的数 .1 默认是一个丑数. e.g. 8 = 2*2*2; 18 = 2*3*3 都是丑数 直观想法是: 判断一个数是否是丑数,如果它能被2整除,则一直除以2,同理能被3,5整除