吴昊品游戏核心算法(新年特别篇)—— 吴昊教你玩小鸟跳跳(DP)

 

 如图所示,这是一款android的跳格子游戏(名字叫小鸟跳跳,图中的游戏为第二版)——红色的格子只能跳一次,黄色的格子可以跳2次,控制小鸟从起点跳到终点

 我 们的目的是使小鸟可以到达终点,注意,这里的到达也许表述地并不是很清晰,应该说,是到达且恰好到达终点,这应该说是有一定的难度的,毕竟是多一步或者少 一步也是不行的(想当年我玩飞行棋的时候也在这个方面吃过不少的亏,明明飞机就要进入终点了,但是就因为哪怕是一步,就一直徘徊在那里,真心郁闷啊!)

 模型的简化

 

 一 个人力无法预测的原因,我无法传图片了,郁闷中,我就只能说明一下图片的来源了(Source:HDOJ 1208),这里,我们每踩到一个小格子,都可以选择向右或者向下走(起点在左上角,终点在右下角,向上走或者向左走都是不可以的,因为这样的话会造成某 种“迂回”策略)

  DP策略

给出这样一个矩阵,问从map[1][1] map[n][n],有几种不同的跳法。

map[ i ][ j ]表示跳几格   f [ i ][ j ] 表示有几种条法

其实就是一个子状态继承问题,如果map[ i ][ j ]k,那么 f [ i+k ][ j ] f[i][j+k] 就可以增加 f [ i ][ j ]种跳跃方法了。

 

  Solve:

  

 1  #include<stdio.h>
 2  #include< string.h>
 3  
 4   int map[ 50][ 50];
 5  __int64 f[ 50][ 50];
 6  
 7   int main()
 8  {
 9     int i,j,n;
10     char s[ 50];
11     // 读取案例数到文件尾
12      while(scanf( " %d ",&n)!=EOF)
13    {
14       // 由于需要用gets来读一行,所以利用getchar()读掉一个回车
15       getchar();
16       if(n==- 1)
17         return  0;
18       // 读入数字串并将其转为int型的二维数组
19        for(i= 0;i<n;i++)
20      {
21        gets(s);
22         for(j= 0;j<n;j++)
23          map[i][j]=s[j]- ' 0 ';                
24      }                      
25       // 初始化f数组,这里,有些编译器是可以自动实现的
26       memset(f, 0, sizeof(f));
27       // 到达最开始的那个点(左上角)有1种走法
28       f[ 0][ 0]= 1;
29       for(i= 0;i<n;i++)
30         for(j= 0;j<n;j++)
31        {
32           // 等于0相当于是一个"死点"
33            if(map[i][j]== 0)
34             continue;
35           // 有向右和向下两个方向,分别存储状态值
36           f[i+map[i][j]][j]+=f[i][j];
37          f[i][j+map[i][j]]+=f[i][j];                
38        }    
39      printf( " %I64d\n ",f[n- 1][n- 1]);
40    }
41     return  0;    
42  }
43  
44 
45 


你可能感兴趣的:(算法)