UVa 1575 Factors
题意:
令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) {;}
作者:乌鸦坐飞机
出处:http://www.cnblogs.com/whistle13326/
新的风暴已经出现
怎么能够停止不前
穿越时空 竭尽全力
我会来到你身边
微笑面对危险
梦想成真不会遥远
鼓起勇气 坚定向前
奇迹一定会出现