自然数和分解
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
5
题解
解法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); }