递归思想做穷举随想

放3个题目,选自老师的讲稿:

第一个问题
问题1出栈序列
1.考虑组成要素。
影响结果的是栈内和栈外的元素个数,因此,组成要素可以暂定为这两个,可以写成函数f(x,y),x表示为外面的元素个数,y为里面的元素个数。

2.画图分析(画图是个很有用的东西)
题目一分析
分析:
(1)结束条件:x=0时,只能出栈了;y=0时,无法处理。
(2)发展:从初始状态(0,0)发展到结束条件,可以通过出栈和入栈来达到。出栈可以用f(x,y-1)实现,条件是y>0;入栈可以用f(x-1,y+1)实现,条件是x>0。

3.于是,可得代码:题目一代码
这里的出栈条件是内部元素个数大于0,入栈条件是,外部元素大于0,上面的代码为了精简,对外部元素等于1的情况直接加了1(没必要再进入和判断)。

第二个问题
问题二
1.考虑组成要素。
影响结果的是拿50元的人数和拿100元的人数,因此,组成要素可以暂定为这两个,可以写成函数f(x,y),x表示为50元的人数,y为100元的人数。

2.分析
(1)结束条件
起源是y=0,x>0的时候,相当于只能出栈,所以返回的是1.
(2)发展
假设一开始,是x>y>0的情况,从初始到y=0,x>0的情况,是通过每减少一个人来实现的。那可能减少的是x里的人,也有可能减少的是y里的人。因此过程的转移可以写为f(x-1,y)和f(x,y-1)。因此,x和y的关系是,如果x<y,则100块钱的人没钱找,无法处理;如果x>y,考虑(x-1,y)和(x,y-1)的情况,用递归来做。

(3)问题最终的解决
求总方案数,那就把转移时两种情况的方案加起来即可。

3.代码
题目二代码

第三个问题
一次数学课堂练习有n道题,老师先写出一个,然后每隔5分钟又写出一个.规定:(1)每个学生在老师写出一个新题时,如果原有题还没有做完,那么必须立即停下来转做新题;(2)做完一道题时,如果老师没有写出新题,那么就转做前面相邻未解出的题.解完各题的不同顺序共有多少种可能?

1.考虑组成要素。
影响结果的是老师的题数和学生完成的题数数,因此,组成要素可以暂定为这两个,可以写成函数f(x,y),x表示为老师的题数,y为学生完成的题数。

2.分析
(1)结束条件
我们把老师出相邻的两道题的过程看作一个过程。当老师出够n道题了,就结束。我们用(x,y)来表示某一状态结束时,老师出的题数和学生完成的题数,那么到x=n-1时就结束了,因为出到第n题后,没有题目进栈了,只能出栈返回值1,这一步可以不代入。

(2)发展
老师题目一开始是0题,每个过程增加1题,学生在这个过程中可以做0到n-1题(因为还有下一题,故是n-1题),n-1在这里要做讨论,如果此时y>x,是不可能的,无法处理;否则,进入下一个状态。

(3)代码

#include<iostream>
using namespace std;
int f(int x,int y);

int n;
int main()
{
    
    
	scanf("%d",&n);
	cout<<f(0,0)<<endl;
	system("pause");
	return 0;
}

int f(int x,int y)
{
    
    
	int c=0;
	if(y>x)
		return 0;
	if(x==n-1)
		return 1;
	for(int i=0;i<n;i++)
		c+=f(x+1,y+i);
	return c;
}

水平有限,如有疏漏之处,请多多包涵!

Guess you like

Origin blog.csdn.net/ChaoyingL/article/details/118363739