吴昊品游戏核心算法(新年特别篇)—— 吴昊教你玩小鸟跳跳(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 


posted on 2013-02-28 12:27  吴昊系列  阅读(212)  评论(0编辑  收藏  举报

导航