UVA 1575 - Factors

令 f(k)=n 表示 有 n 种方式,可以把正整数 k 表示成几个素数的乘积的形式。
例 10=2*5=5*2,所以 f(10)=2
给出 n,求最小的 k

 

 

 

搜索

从最小的质数开始枚举选几个

假设前i-1个种质数用了k个,有sum种方案,第i种质数选a个,

那么前i种质数的方案就有sum*C[k+a][a]

可以理解原来有k个位置,又加了a个位置,有a个数可以放在任意位置

所以前i种的每一种方案都变成C[k+a][a]种

 

枚举每个质数选几个时,如果上一个质数选了k个,那么这一个质数最多选k个

假设这个质数选了k+1个,那么显然上一个质数选k+1个,这个选k个更优

 

注意整数类型上限

(copy原地址)

屠龙宝刀点击就送

#include<cstdio>
typedef unsigned long long LL;
int p[21]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71};
LL ans,n;
LL C[70][70];
void solve(int num,int lim,LL tot,LL now,int last)
{
    if(now>ans) return;
    if(tot==n) { ans=now; return ; }
    if(tot>n || num>20) return;
    LL t=1;
    for(int i=1;i<=lim;i++)
    {
        t*=p[num];
        if(now>=ans/t) return;
        solve(num+1,i,tot*C[last+i][i],now*t,last+i);
    }
}
int main()
{
    C[0][0]=1;
    for(int i=1;i<70;i++)
    {
        C[i][0]=1;
        for(int j=1;j<=i;j++)
            C[i][j]=C[i-1][j-1]+C[i-1][j];
    } 
    while(scanf("%lld",&n)!=EOF)
    {
        if(n==1)
        {
               printf("1 2\n");
               continue;
        }
        ans=(LL)1<<63;
        solve(1,63,1,1,0);
        printf("%lld ",n);printf("%lld\n",ans);
    }
    return 0;
}

 

posted @ 2017-09-22 16:42  杀猪状元  阅读(350)  评论(0编辑  收藏  举报