简单的整数划分问题
递归法
定义函数f(m,i);
m为要凑的数,i是第i个使用的数
递归分析
基础部分:
如果m为0就是只有“一个”方案:谁都不取。
如果n为零没有数了谁都凑不了/
if(m==0){
return 1;
}
if(i==0){
return 0;
}
递归部分:
对于f(m,i):要么取第i个要么不取第i个,注意可以重复取。
if (m >= i) {
return divide(m - i, i) + divide(m, i - 1);//之所以时d(m-i,i)不是d(m-i,i-1)是因为第n位可以重复取
}
else {
return divide(m, i - 1);
}
动态规划法(记忆化,不完全
性能比较
递归
动态规划
因为N小于等于50所以递归81ms可以过。
下面给一个1ms过的方法:
发现你在递归中有大量重叠,考虑记忆化。用一个数组存储。
#include <iostream>
using namespace std;
int con[100][100];
int divide(int m , int i) {
if (m == 0)
return 1;
if (i == 0)
return 0;
if (m >= i) {
if (con[m - i][i] == -1)
con[m - i][i] = divide(m - i, i);
if (con[m][i - 1] == -1)
con[m][i - 1] = divide(m, i - 1);
return con[m - i][i] + con[m][i - 1];
}
else {
if (con[m][i - 1] == -1)
con[m][i - 1] = divide(m, i - 1);
return con[m][i - 1];
}
}
int main(int argc, char const *argv[])
{
int i ;
ios::sync_with_stdio(false);
while (cin >> i) {
for (int i = 0; i < 100; ++i)
for (int ii = 0; ii < 100 ; ++ii)
con[i][ii] = -1;
cout << divide(i, i) << endl;
}
return 0;
}