1.純遞迴
設函數func(int n, int m) 定義為計算 把整數 n 劃分為 小於或等於 m 的一系列數字之和 的劃分方法有多少種,則對於:
(1)當 n == 1 時,無論 m 取何值,都只能 劃分為 1;
(2)當 m == 1 時 ,無論 n 為何值, 也只能劃分為 n 個 1 相加 ,只有一種劃分方法;
(3)當 n < m, 顯然 func(n, m) = func(n , n);
(4)當 n > m 時, 可分兩種情況討論,
(1)劃分中包含 m 時, 有func(n -m, m) 種劃分方法;
(2)劃分中不包含 m 時, 有 func(n, m-1)種劃分方法;
所以 func(n ,m) = func(n -m, m) + func(n, m-1);
(5)當 n == m 時,當劃分包含 m 時, m = m ,只有一種劃分方法;
當 不包含 m 時, 有 func(n, m-1) 種劃分方法。
根據以上分析:
func( n, n ) = 1, 當 n ==1;
func( n, n ) = 1, 當m == 1;
func( n, n ) = func( n,n ) , 當n < m;
func( n, n ) = func( n, m-1) +1 , 當n == m;
func( n, n ) = func ( n - m, m ) + func ( n , m -1) , 當n > m;
相應的代碼如下:
/* * 1.cpp * * Created on: 2017年9月01日 * Author: Administrator */#include <iostream>using namespace std;int func(int n, int m){if(n == 1 || m == 1){return 1;}else if(n < m){return func(n,n);}else if (n == m) {return func(n,m-1)+1;} else if(n >= m){return func(n,m-1) + func(n-m,m);}}int main(){int n;while(cin>>n){cout<<func(n,n)<<endl;}return 0;}
2.記憶型遞迴:
/* * 1.cpp * * Created on: 2017年9月01日 * Author: Administrator */#include <iostream>#include <string.h>using namespace std;const int maxN = 1000;int dp[maxN][maxN];int func(int n, int m){if(n == 1 || m == 1){return 1;}else if(n < m){if( dp[n][m] != -1 ){return dp[n][m];}else{return dp[n][m] = func(n,n);}}else if (n == m) {if( dp[n][m] != -1 ){return dp[n][m];}else{return dp[n][m] = func(n,m-1)+1;}} else if(n > m){return dp[n][m] = func(n,m-1) + func(n-m,m);}}int main(){int n;memset(dp,-1,sizeof(dp));while(cin>>n){cout<<func(n,n)<<endl;}return 0;}
3.動態規劃:
/* * 1.cpp * * Created on: 2017年9月01日 * Author: Administrator */#include<cstdio>#include<iostream>using namespace std;#define N 55int f[N][N];int main(){int n; while(cin>>n){ n++; for(int j=1;j<=n;j++){ f[1][j]=1; for(int i=2;i<=n;i++){ if(i<j) f[i][j]=f[i][j-1]; else f[i][j]=f[i-j][j]+f[i][j-1]; } } printf("%d\n",f[n][n]); }}