POJ 3421 多重组合排列

Given a positive integer X, an X-factor chain of length m is a sequence of integers,

1 = X0, X1, X2, …, Xm = X

satisfying

Xi < Xi+1 and Xi | Xi+1 where a | b means a perfectly divides into b.

Now we are interested in the maximum length of X-factor chains and the number of chains of such length.

Input

The input consists of several test cases. Each contains a positive integer X (X ≤ 220).

Output

For each test case, output the maximum length and the number of such X-factors chains.

Sample Input

2
3
4
10
100

Sample Output

1 1
1 1
2 1
2 2
4 6

题目大意:一个整数n,然后分解它的因子从X0到Xm,其中X(k+1)>Xk且Xk整除X(k+1),即X(k+1)%Xk==0,让你求出这样的序列的最长长度,当然这个长度你可以理解为下标m(从0开始的),也可以理解成所有的因子不包含1的个数,然后输出的下一个数是存在长度为m这样的因子序列有几个;

分析:因子问题,可以想到向质因子考虑,因为任何一个整数都是由其质因子相乘得到的,因此可以对整数分解质因子,对于最长链的长度可以这样求:拿样例n=100来说,它的质因子有1,2,5,其中2有两个,5有2个(这点很重要),它的题目要求最长链的因子都是由前一项乘以一个质因子得到的:

举个栗子:100存在这样一个符合题意的样例 1 ,2 ,4 ,20 ,100,然后对其分解变成1,2,2*2,2*2*5,2*2*5*5,这样就可以明显看出我上面的那一句是什么意思,20>4,20%4==0,那么20,相对于4就是4乘以一个质因子5得到的20,最终就是将所有的质因子相乘得到整数n(这样才是最长的,2最多有2个,5最多也有2个,因此答案不可能出现3个2或者3个5相乘的因子的情况),因此最长的链的长度就是所有质因子个数的相加的和;

然后再求最长链的个数问题,在这里我是参考了这位博主的思路来理解的:传送

然后就是多重集全排列的问题了

https://blog.csdn.net/silence401/article/details/52787782?locationnum=10&fps=1

https://blog.csdn.net/theArcticOcean/article/details/46794101?utm_source=blogxgwz3

综上:其组合数为N!/ (N1! *N2! * N3! *Nm!)

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <cstring>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define lep(i,l,r) for(int i=l;i>=r;i--)
const int N=1e4;
int prime[N];
int factor(int n){
    int tot=0;
    for(int i=2;i*i<=n;i++){
        if(n%i==0) {
        n/=i;
        prime[++tot]++;
        while(n%i==0) n/=i,prime[tot]++;
        }
    }
    if(n>1) prime[++tot]++;
    return tot;
}
ll Sum(int v){
    ll ans=0;
    for(int i=1;i<=v;i++) ans+=prime[i];
    return ans;
}
ll Sum1(ll num,int u)
{
    ll base=1;
    for(int i=2;i<=num;i++)
        base*=i;
        for(int k=1;k<=u;k++){
            ll t=1;
            for(int j=2;j<=prime[k];j++)
            t*=j;
        base/=t;
        }
    return base;
}
int main(){
    int n;
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    #endif // ONLINE_JUDGE
    while(scanf("%d",&n)!=EOF){
            memset(prime,0,sizeof prime);
    int sum=factor(n);
    ll len=Sum(sum);
    ll ans=Sum1(len,sum);
    printf("%lld %lld\n",len,ans);
    }
}

猜你喜欢

转载自blog.csdn.net/c___c18/article/details/83096395