hdu 1978 How many ways 记忆化搜索+DP

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1978

思路很好想;

定义f[i][j]表示从点(i,j)出发到达(n,m)的方法数;

那么对于一切从(i,j)可以到达的点来说,f[i][j]+=∑f[k][p];其中(k.p)表示(i,j)可以到达的点,应该比较好理解的吧;

最后可以通过DFS  求解每一个点到达(n,m)的方案数,答案就为f[1][1];

注意的一点是:

在DFS过程中要保留答案状态,避免重复计算。即所谓的记忆化。

代码如下:

 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<cstdio>
 5 using namespace std;
 6 #define MAX 110
 7 #define MOD 10000
 8 int n,m;
 9 int map[MAX][MAX];
10 int ans;
11 int f[MAX][MAX];
12 int dfs(int x,int y)
13 {
14         if(x==n&&y==m) {f[n][m]=1;return  1;}
15         int power=map[x][y];
16         if(power==0) return -1;
17         for(int i=x;i<=x+power;i++)
18            for(int j=y;j<=y+power-(i-x);j++)
19                   {
20 
21                           if(i==x&&j==y) continue;
22                           if(i>n||i<0||j>m||j<0) continue;
23                           if(f[i][j]==0)
24                           {
25                             f[i][j]=dfs(i,j);
26                           }
27                           if(f[i][j]>0) {f[x][y]+=f[i][j];f[x][y]=f[x][y]%MOD;}
28                           if(f[i][j]==-1) continue;
29                   }
30                   return f[x][y];
31 }
32 int main()
33 {
34       int t;
35       scanf("%d",&t);
36       while(t--)
37       {
38           memset(f,0,sizeof(f));
39           scanf("%d%d",&n,&m);
40           for(int i=1;i<=n;i++)
41                   for(int j=1;j<=m;j++)
42                         scanf("%d",&map[i][j]);
43          dfs(1,1);
44          cout<<f[1][1]<<endl;
45       }
46       return 0;
47 }
View Code

 

 

posted on 2013-08-08 21:25  GyyZyp  阅读(169)  评论(0编辑  收藏  举报

导航