【方案数】 递推如何解决?CCF1171
本文为作者原创。
这是我第一次写博客,不便之处请谅解。
方案数
题目描述:
有一个类似弹球的游戏,如下图,小球从上下滑落,每次到一个交叉点都有两种选择:向左或向右滑落,如果有一个球从顶端滑落到低端有多少种走法?特别是交叉点中有一些陷阱,小球掉进陷阱就不能走了。
首先来看一下样例:
1.定义了一个四行的三角形
2.三排第二个点是陷阱
不难理解,小球从上方到第三行路径有2条,第四行有4条,所以一共只有4条路径可走。
如果用递归,那么我们要从顶部往下,每一个点都引申出左下和右下两个点,每当遇上陷阱,就返回0, 表示没有路可走。
但这样太慢了!
为什么呢?
因为跟数字三角形那一道经典题一样,递归的点重复了,三角形的行数越多,重复调用的次数更是翻倍激增。
那么该如何解决呢?
我们可以用递归。
递归思路:
1.把三角形底部都设置成1
2.从下往上递推,两个点相加放在上面那个点里
3.遇上陷阱就把上面那一个点变为0
4.最上面的点就是结果了
代码实现:
1 #include<cstdio> 2 #include<iostream> 3 using namespace std; 4 int main(){ 5 int a[100][100],n,m,x,y; 6 cin>>n>>m; 7 for(int i=0;i<m;++i){ 8 cin>>x>>y; 9 a[x-1][y-1]=-1;//标志陷阱 10 } 11 for(int i=0;i<n;++i){ 12 a[n-1][i]=1;//第一步 13 } 14 for(int i=n-2;i>=0;i--){ 15 for(int j=0;j<=i;j++){ 16 if(a[i][j]==-1){ 17 a[i][j]=0;//第三步 18 continue; 19 } 20 else { 21 a[i][j]=a[i+1][j]+a[i+1][j+1];//第二步 22 } 23 } 24 } 25 cout<<a[0][0];//第四步 26 return 0; 27 }
于是题目就通过了!
时间复杂度:O(n)。
posted on 2017-09-10 20:05 Come-true! 阅读(76) 评论(0) 收藏 举报
浙公网安备 33010602011771号