标签:mes ret 接下来 小根堆 main soft mem mic 最小
这题主要是两种做法,第一种是比较常(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行是重要的,因为如果这个素数的地址并没有满足要求,那么它在下一次美剧
标签:mes ret 接下来 小根堆 main soft mem mic 最小
原文地址:http://www.cnblogs.com/ShuraK/p/7846412.html