洛谷P1463 [POI2001][HAOI2007]反素数

@Pelom  October 12, 2021

题意:

求不大于 $n$ 的最大高合成数

高合成数指一个数,任何比它小的自然数的因子数目均比这个数的因子数目少。

数据范围: $1 \le N \le 2000000000$

题解:

对于一个数 $x$ ,由算术基本定理$$x=\prod p_i^{a_i}$$则其因子数目为$$\prod (a_i+1)$$
根据贪心,在因子数目数目一定时,$x$ 应为最小,此时 $x$ 才为高合成数。
不妨设 $p_i$ 单调递增,为让 $x$ 尽量小,显然 $a_i$ 应单调递减:
若 $\exists$ $p_i < p_j$ 且 $a_i < a_j$ ,那么这个数显然不是高合成数,因为交换 $a_i$ 与 $a_j$ 会构造出更小的数,从而使其不满足定义。
于是可以据此搜索,其中使用到的素数可以打表,因为最多使用到 $12$ 个素数,其乘积已满足题目数据范围,况且数据越大,其使用到的较小素数越多。

代码:

#include<iostream>
#include<cstdio>
using namespace std;
#define LL long long
int n;
int pri[]={0,2,3,5,7,11,13,17,19,23,29,31};
LL ans,mxcnt;
void dfs(LL sum,int x,int cnt,int p){
    if(x>=12){
        if(cnt>mxcnt || (cnt==mxcnt && sum<ans)){
            mxcnt=cnt;
            ans=sum;
        }
        return ;
    }
    LL t=1;
    for(int i=0;i<=p;i++){
        dfs(sum*t,x+1,cnt*(i+1),i);
        t*=pri[x];
        if(sum*t>n)
            break;
    }
}
int main(){
    scanf("%d",&n);
    dfs(1,1,1,12);
    printf("%lld",ans);
    return 0;
}

添加新评论