【Codevs2549/2548】自然数和/积分解

自然数和分解

Description

把自然数N分解为若干个自然数之和,输出方案数。

Input

N,(1≤n≤50)

Output

方案数

Sample Input

5

Sample Output

7

HINT

5 可分为

1 1 1 1 1
1 1 1 2
1 1 3
1 2 2
1 4
2 3

题解

解法1:完全背包

#include<iostream>
#include<cstdio>
using namespace std;
int n,ans;
int a [55]; 
int main()
{
    scanf("%d",&n);
    a[0] = 1;
    for (int i=1;i<=n;i++)
        for (int j=1;j<=n;j++)
        {
            if (j>=i)
                a[j] += a[j-i];
        }
    printf("%d",a[n]);
}

解法2:搜索

x表示在上一步中减去哪个数,rest表示剩下的数。

当rest为0时得到一种方案

i : x->rest 保证了不会重复

#include<iostream>
#include<cstdio>
using namespace std;
int ans,n;
void dfs(int x,int rs)
{
    if (rs == 0)
    {
        ans++; return;
    }
    for (int i=x;i<=rs;i++)
        dfs(i,rs-i);
}
int main()
{
    scanf("%d",&n);
    dfs(1,n);
    cout<<ans;
}

自然数积分解

Description

把自然数N分解为若干个自然数之积,输出方案数。

Input

自然数N,(1≤n≤2000000000)

Output

方案数

Sample Input

20

Sample Output

4

HINT

20 可分为

20 
4 5
2 10
2 2 5

题解

和上边那题一样,当rest等于1时得到一个答案

60分

#include<iostream>
#include<cstdio>
using namespace std;
int n,ans;
void dfs(int x,int rs)
{
    if (rs == 1) ans++;
    for (int i=x;i<=rs;i++)
        if (rs % i ==0 && i!=1)
            dfs(i,rs/i);
}
int main()
{
    scanf("%d",&n);
    dfs(1,n);
    printf("%d",ans);
}

这个题数据范围太大,需要优化。

当找到一个i使得rs模i=0时,就说明找到了一组解,而约数可能还可以继续分解

#include<iostream>
#include<cstdio>
#include<cmath> 
using namespace std;
int n,ans=1;
void dfs(int x,int rs)
{
    for (int i=x;i<=sqrt(rs);i++)
        if (rs % i ==0)
            ans++,dfs(i,rs/i);
}
int main()
{
    scanf("%d",&n);
    dfs(2,n);
    printf("%d",ans);
}
原文地址:https://www.cnblogs.com/liumengyue/p/5574116.html