UVa 1575 Factors

来源:互联网 发布:sql identity是什么 编辑:程序博客网 时间:2024/05/19 15:40
链接

题意:

令f(k)=n 表示 有n种方式,可以把正整数k表示成几个数的乘积的形式。

例 10=2*5=5*2,所以f(10)=2

给出n,求最小的k

 

组合数忘了开long long 连WA15次 我真的傻了。

 

这个和反素数有点像

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

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

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

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

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

 

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

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

 

 1 #include <cctype> 2 #include <cstdio> 3  4 typedef unsigned long long LL; 5  6 const int MAXN=100; 7  8 LL ans,n; 9 10 LL C[MAXN][MAXN];11 12 int prime[21]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71};13 14 inline void pre() {15     C[0][0]=1;16     for(int i=1;i<70;i++) {17         C[i][0]=1;18         for(int j=1;j<=i;j++)19             C[i][j]=C[i-1][j-1]+C[i-1][j];20     }21 }22 23 void dfs(int num,int limit,LL Np,LL Ans,int last) {24     if(Ans>ans) return;25     if(Np==n) {ans=Ans;return;}26     if(Np>n||num>20) return;27     LL t=1;28     for(int i=1;i<=limit;++i) {29         t*=prime[num];30         if(Ans>=ans/t) return;31         dfs(num+1,i,Np*C[last+i][i],Ans*t,last+i);32     }33 }34 35 int hh() {36     pre();37     while(scanf("%lld",&n)!=EOF) {38         if(n==1) printf("1 2\n");39         else {40             ans=(LL)1<<63;41             dfs(1,63,1,1,0);42             printf("%lld ",n);43             printf("%lld\n",ans);44         }45     }46     return 0;47 }48 49 int sb=hh();50 int main(int argc,char**argv) {;}
代码