算是加深了一丁点对于DP的理解

来源:互联网 发布:无限域名的空间 编辑:程序博客网 时间:2024/05/16 06:06

棋盘里的数学

发布时间: 2016年9月13日 20:39   最后更新: 2016年9月20日 12:04   时间限制: 1000ms   内存限制: 128M

lhcoder有一个n行m列的棋盘,有一颗棋子从左上角(1,1)开始移动,每次只能往右或者往下移动一格,到右下角(n,m)一共有多少移动方案?

有多组测试数据,每组测试数据中有两个整数n和m(2 <= n, m <= 1000),代表为n行m列的棋盘。

一个整数p,代表从左上角(1,1)移动到右下角(n,m)的方案数,由于方案数可能比较大,结果请对99991取模。

 复制
2 2
2
 复制
2 3

3

刚接触DP不久,对于DP这种思想感觉很神奇,很神奇的东西自然很难了。这里这道题是一道记忆化搜索,记忆化搜索和DP的区别我写一下我自己的感受:记忆化搜索是为了减少重复的操作,记忆化嘛,这和走迷宫是一个道理的,一条路已经走过了,并且没找到出口,那么下次再走到这条路的路口时就没必要再走一遍了,这个例子虽说和记忆化搜索有点差别,但这也是我能想出来的最接近记忆化搜索的例子了,但这里要强调的是这个记住的状态必须是到底的状态,说的很模糊,也就只有我自己能够理解,再拿走迷宫来解释这个“到底的状态”,比如说,一条路是 1 5 7 9 3,按我们的记忆化搜索,当我走到1时看看1有没有记住的状态,如果没有就接着往下来走,如果有记住的状态(这条路之前走过),好,停,我所说的“到底的状态”是指:1这个路口标记的状态是 1 5 7 9 3全都走过的状态,而不是 1 5 或者 1 5 7 或者 1 5 7 9 这种状态,我之前写的代码就犯了这个毛病。好,说完了对于记忆化搜索的认识,那就能再讲讲我对于DP的认识,DP普遍被用来解决一个大问题,但这个大问题无法一眼被看出来,但这个问题却可以被分成一个个的小问题,小问题的答案累加起来就是大问题的答案,对于DP我目前就是这么肤浅的理解。


#include<bits/stdc++.h>#define mod 99991using namespace std;int n,m;int chess[1001][1001];int dfs(int x,int y){int cnt=0;if(x==n && y==m)return 1;if(chess[x][y])return chess[x][y];if(x+1<=n){cnt+=dfs(x+1,y);cnt%=mod;}if(y+1<=m){cnt+=dfs(x,y+1);cnt%=mod;}return chess[x][y]=cnt;}int main(){int i,j;while(~scanf("%d %d",&n,&m)){memset(chess,0,sizeof(chess));printf("%d\n",dfs(1,1));}return 0;}


0 0