acwing 198反素数

题目点这里(acwing)
题目点这里(codeforces27E)

题目

对于任何正整数 x,其约数的个数记作 g(x),例如 g(1)=1、g(6)=4。
如果某个正整数 x 满足:对于任意的小于 x 的正整数 i,都有 g(x)>g(i),则称 x 为反素数。
例如,整数 1,2,4,6 等都是反素数。
现在给定一个数 N,请求出不超过 N 的最大的反素数。
输入格式
一个正整数 N。
输出格式
一个整数,表示不超过 N 的最大反素数。
数据范围
1≤N≤2∗109
输入样例:
1000
输出样例:
840

题意:

找到最大的反素数 (约数数目最大的最小的数)
首先我们来三个性质
1 不同的质因子最多到23
因为 2 * 3 * 5 * 7 * 11 * 13 * 17 * 19 * 23 * 29 = 6469693230>2^31-1
所以最多用9个质因子
2 每个质因子次数最大是30
2^31>2*1e9
3 所有质因子的次数递减
由于我们最终总数=各项幂次+1的乘积
基于贪心 我们肯定想在有限的n的情况下总的幂次和越大越好
那么越小的质因子幂次越多 总的幂次肯定越多
对比
A n = 2^2 * 3^4 * 5^5
B n = 2^2 * 3^5 * 5^4
A情况下留给后面的质因子的幂次一定比B少
n = p1^c1 pk^ck
换而言之 当存在非降序时我们通过交换可以让A->B从而乘积更小,进而让总的幂次和更大
即所有质因子的次数递减

#include<iostream>
#include<bits/stdc++.h>
#define int long long 
using namespace std;
int prime[]={2,3,5,7,11,13,17,19,23,29};
int maxd,ans;
int n;
void dfs(int u,int ci,int p,int num)
{
    if(num>maxd||num==maxd&&p<ans)
    {
        maxd=num;
        ans=p;
    }
    if(u==9)return;
    for(int i=1;i<=ci;i++)
    {
        if(p*prime[u]>n)break;
        p*=prime[u];
        dfs(u+1,i,p,num*(i+1));
    }
}
signed main()
{   cin>>n;    
    dfs(0,30,1,1);

    cout<<ans<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值