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

[usaco]丑数

时间:2017-06-11 21:42:17      阅读:252      评论:0      收藏:0      [点我收藏+]

标签:比较   display   ++   cst   stream   src   print   scan   cli   

思考

首先产生的思路是,用小根堆的最小元素(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]);
}

 

[usaco]丑数

标签:比较   display   ++   cst   stream   src   print   scan   cli   

原文地址:http://www.cnblogs.com/OIerLYF/p/6986435.html

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