吴昊品游戏核心算法(新年特别篇) —— 跳格子游戏(DFS+DP)(HDOJ 1978)

“跳格子游戏”应该包括一大类游戏的,现在给出的一种应该算是“实心”的跳格子游戏吧,也就是你可以选择向左走或者向右走,每次走了之后都会触发一系列事 件(这样的游戏有很多,比较简单的一种就是每走到一个格子上面就可以获得一部分积分,在走到终点的时候,需要将获得的积分尽量扩大),你需要选择一种最优 的策略,来让自己获得的利益最大。另外一种属于“空心”的跳格子游戏,类似于“大富翁”,“飞行棋”等等,需要几个人轮流投掷色子,在一个空心的圆环上面 跳格子,地图上的每个格子都会触发一个类似的事件,以此来进行游戏——如图所示的大富翁全地图。我们先看“实心”的跳格子,后面再来看“空心”的跳格子。

 

 

 

  (如图所示,此乃简易的实心跳格子游戏)


 

(如图所示,此乃空心的跳格子游戏)

   现在我们来解决实心的部分,游戏的规则如下:

  1.机器人一开始在棋盘的起始点并有起始点所标有的能量。
  2.机器人只能向右或者向下走,并且每走一步消耗一单位能量。
  3.机器人不能在原地停留。
  4.当机器人选择了一条可行路径后,当他走到这条路径的终点时,他将只有终点所标记的能量。

  (Source:HDOJ 1978)输入整个棋盘,输出需要对10000取模。值得注意的一点是,这里不是在计算最优值,而是要计算所有可能的路线,所以,在使用DP存储以前的路线的时候,要全部保留,不能做一些舍入。

 

 1  /*
 2   Highlights:
 3              (1)深搜时,由于只能往右或者下方向走,所以加上了i<=step和i+j<=step的条件
 4              (2)不要留到最后取模,这样会出现溢出的危险
 5              (3)利用sum[x][y]存储一些中间值
 6              (4)初始化的时候,将所有的格子的可能步数调节到"不可能"的程度  
 7  */
 8  #include<stdio.h>
 9  #include<stdio.h>
10  #include<iostream>
11  using namespace std;
12  
13  //常量,N代表行数,M代表列数
14  const int N=101,M=101;
15  //利用grid二维数组定义整个地图
16  int grid[N][M];
17  int sum[N][M]; //以(i,j)为起点到(n,m)的路的条数
18  int n,m;
19  
20  //深搜,根据能量值调节搜索的深度
21  int dfs(int x,int y)
22  {
23    if(x==n&&y==m)
24      return 1;  //(n,m)到(n,m)条数为1
25    if(sum[x][y]!=-1)
26      return sum[x][y];  //如果曾经访问过,返回记忆中的内容
27    int step=grid[x][y];
28    int num=0//能量值,即可以走的步数
29    //这里,由于只能往右或者下方向走,所以加上了i<=step和i+j<=step的条件
30    for(int i=0;i<=step;i++)
31      for(int j=0;i+j<=step;j++)
32      {
33        if(!(i==0&&j==0)&&x+i<=n&&y+j<=m)
34        {  
35          //i=0,j=0,说明没有走动
36          num+=dfs(x+i,y+j);
37          //及时取模,防止数据溢出
38          num%=10000;
39        }
40      }
41    sum[x][y]=num; //记忆
42    return num;
43  }
44 
45  int main()
46  {
47    int t,i,x,k,j,v;
48    //C++的输入输出和C的输入输出混到一起用了!!!
49    cin>>t;
50    while(t--)
51    {
52      scanf("%d%d",&n,&m);
53      for(i=1;i<=n;i++)
54        for(j=1;j<=m;j++)
55          scanf("%d",&grid[i][j]);
56      memset(sum,-1,sizeof(sum)); //初始化,将每一个的数字调节到"无限或者至少是在这个游戏中最可能的小"
57      printf("%d\n",dfs(1,1)); //从(1,1)走到(n,m)的值
58    }
59    return 0;
60  }
61 
62 

 

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

导航