读书人

C++写下楼梯有关问题小算法时碰到的有

发布时间: 2012-02-25 10:01:49 作者: rapoo

C++写下楼梯问题小算法时碰到的问题
下楼问题:假设总共有n级台阶,每一步能走3阶、2阶或者1阶,n在程序运行时输入,求共有多少种下楼方案。
下面是我的代码:

#include <iostream>
using namespace std;

int i,k=1,count=1,num=0; //方案数num
int take[100]; //记录每步走的台阶数
void Try(int n) //被调用函数
{

int j; //定义整型变量j表示每步允许走的台阶数

for(j=3;j>0;j--)
{

if (n<j) continue;
else //n>=j
{
take[count]=j; //记录第count步走了j个台阶
count++;
if(n==j) // 如果已经走到了楼下,做下列事情
{
num++; //方案数加1
cout<<"方案"<<num<<": "; //输出方案
for(i=k;i<count;i++) //输出方案的每一步
cout<<take[i]<<" ";
cout<<endl;
k=count;
}
else //尚未走到楼下
Try(n-j);
}
}
}

void main()
{
int h;
cout<<"请输入有多少个台阶:";
cin>>h;

Try(h);

//输出总的解决方案数
cout<<"总方案数:"<<num<<endl;
getchar();
getchar();
}
由于层层递归的原因,算法结果输出地时候得不到想要的结果,请各位帮忙解决一下

[解决办法]

C/C++ code
//因为增长很快,所以要输出结果的话就输出得太多了。//可以直接写个递推求方法数,注意不要搞溢出了。#include <iostream>using namespace std;int ans[20] = {1};int main(){    for (int i = 1; i <= 19; ++i)    {        for (int t = 1; t <= 3; ++t)        if (i - t >= 0) ans[i] += ans[i-t];        cout << ans[i] << endl;    }    return 0;}
[解决办法]
可以看成是子问题,第i个台阶的方案数是第i-t个方案数加1,t是1,2,3,加1表示最后一步走t个台阶。
原题想输出的话,递归调用堆栈溢出了。
[解决办法]
n>4时,走n阶台阶的方法数是最后一步走3阶的方法数:f(n-3),最后一步走两阶的方法数:f(n-2),最后一步走1阶的方法数:f(n-1),的和。
递归公式为:f(n)=f(n-1)+f(n-2)+f(n-3) (n > 4) 且f(1)=1,f(2)=2,f(3)=3
[解决办法]
完成了。。

还可以进行优化,这里只是最简单的实现。
C/C++ code
 

#include <iostream>
using namespace std;
class Int
{
friend bool operator <=(Int &a, Int &b);
friend ostream &operator < <(ostream &o, Int &a);
private:
int n;//0-(n-1)
char *p;
void jj(int _n);//1对应n-1

public:
Int(int/*位数*/, char/*每位的值*/);
//返回指定位数的数值。
char find(int/*位数*/);
void operator ++(int);

~Int();
};
void Int::jj(int _n)//1对应n-1
{

p[n - _n] ++;
if(p[n - _n] > '4')
{
p[n - _n] = '1';
jj(_n + 1);
}
}
Int::Int(int n, char x)
{
this->n = n;
p = new char[n];
for(int i = 0;i < n;i ++)
{
p[i] = x;
}
}
Int::~Int()
{
if(p)
{
delete[] p;
p = 0;
}
}

char Int::find(int n/*base 1*/)
{
//不进行大小判断了,专注于这个问题。

return p[n - 1];
}
void Int::operator ++(int)
{
jj(1);
}

bool operator <=(Int &a, Int &b)
{
//针对这个问题的。。所以a.n == b.n
char *_a = a.p, *_b = b.p;
for(int i = 0;i < a.n;i ++)
{
if(_b[i] > _a[i])
{
return true;
}
else
{
if(_b[i] == _a[i])
{
continue;
}
else
{
return false;
}
}
}
return true;
}
ostream &operator < <(ostream &o, Int &a)


{
char *p = a.p;
for(int i = 0;i < a.n;i ++)
{
o < < p[i];
}
return o;
}
int f2(int a, int b, int c);
void f1(int n)
{
int a, b, c;
int num = 0;//解决方案数量
for(a = 0;a <= n/*为了方便直接n了*/ ;a ++)
{
for(b = 0;b <= n/*同上*/;b ++)
{
for(c = 0;c <= n;c ++)
{
if(a * 3 + b * 2 + c ==n)
{
num += f2(a, b, c);
}
}
}
}
cout < <n < <"个阶梯时,共有" < <num < <"个解决方案" < <endl;
}

int f2(int a, int b, int c)
{
int abc = a + b + c;
Int min(abc, '1');
Int max(abc, '3');
int num = 0;//固定(指a、b、c确定)下的解决方案数量
for(;min <= max;min ++)
{
int _a = 0, _b = 0, _c = 0;//分别为里面数目的值
for(int k = 1;k <= abc;k ++)
{
switch(min.find(k))
{
case '3':
_a ++;
break;
case '2':
_b ++;
break;
case '1':
_c ++;
break;
default:
goto gg;
}
}
if((a == _a) && (b == _b) && (c == _c))
{
num ++;
//也可以存放在数据结构里,以后再输出,为了方便这里直接输出。
cout < < min < < endl;
}
gg:;

}
return num;
}

int main()
{
int n = 11;
f1(n);

}


读书人网 >C++

热点推荐