數的拆分 遞歸做法(xdoj 1096)

比賽時候看到這道題的我的內心是崩潰的啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
清晰的記得數據結構課上老師一步一步給推過這個問題的遞推式,然而我忘記了啊啊啊啊啊啊啊啊啊啊啊啊
果然出來混都是要還的,不好好聽課的結果就是隻能自己手推一遍。。。。好了進入正題。

先貼題目 西電oj 1096 http://acm.xidian.edu.cn/problem.php?id=1096

先舉幾個例子
1 的拆分數 1
##1
2 的拆分數 2
## 1+1
## 2
3 的拆分數 3
## 1+1+1
## 1+2
## 3
4 的拆分數 5
## 1+1+1+1
## 1+1+2
## 1+3
## 2+2
## 4
5 的拆分數 7
## 1+1+1+1+1
## 1+1+1+2
## 1+2+2
## 1+1+3
## 2+3
## 1+4
## 5
6 的拆分數 11
## 1+1+1+1+1+1
## 1+1+1+1+2
## 1+1+2+2
## 2+2+2
## 3+1+1+1
## 3+2+1
## 3+3
## 4+1+1
## 4+2
## 5+1
## 6
7 的拆分數 15 。。。

設n爲待拆分的數。m爲 拆分組合中的最大數。f(n,m)爲待求的拆分數
f(6,6)=11
f(6,5)=10
f(6,4)=9
f(6,3)=7
f(6,2)=4

好了,接下來考慮邊界情況。
1。n==1或者m==1時 f(n,m)=1
2。n==m時 f(n,m)= f(n,n-1)+1 //eg:f(6,6)=f(6,5)+1
####這裏的 1 剛好是 拆分組合中的 6
3。m > n時 f(n,m)=f(n,n) //嚴格說這種情況是無意義的。應該很好理解
4。m < n時 f(n,m)=f(n,m-1)+f(n-m,m) //這是一般情況,下面重點解釋一下這個
#############
以f(6,4)爲例
f(6,4)=9
## 1+1+1+1+1+1
## 1+1+1+1+2
## 1+1+2+2
## 2+2+2
## 3+1+1+1
## 3+2+1
## 3+3
## 4+1+1
## 4+2
f(6,3)=7
## 1+1+1+1+1+1
## 1+1+1+1+2
## 1+1+2+2
## 2+2+2
## 3+1+1+1
## 3+2+1
## 3+3
f(2,4)=f(2,2)=2
##1+1
## 2
比較一下就會發現f(6,4)中的4+1+14+2 去掉前面的4 ,剛好等於f(2,2)中的1+12
#################

然後如果題中不需要n這個數本身,輸出的時候-1就可以啦~~~
代碼:

#include <iostream>
#include<stdio.h>
using namespace std;

int f(int n,int m)
{
    if(n==1||m==1)  return 1;
    else if(m==n) return f(n,n-1)+1;
    else if(m>n)  return f(n,n);
    else return f(n,m-1)+f(n-m,m);
}

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        printf("%d\n",f(n,n)-1);
    }

    return 0;
}

over~~~~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章