-
http://ac.nbutoj.com/Problem/view.xhtml?id=1350
-
[1350] 气坏了老虎乐坏了兔
- 时间限制: 2000 ms 内存限制: 65535 K
- 问题描述
-
这天小灰兔又把老虎给气坏了,于是就偷着乐呢。
小灰兔欢乐的时候就爱弹琴。所谓的琴不是一般的琴,而且很大,弹琴的时候,小灰兔需要站在各个琴键上跳动到另一个琴键。
所有琴键放在一个N * N的琴架上,一共N行琴键,每行N个琴键。
小灰兔只能从一个琴键跳到周围共享一边的四个琴键上。
问小灰兔如果从任意一个琴键开始弹一首需要跳M格琴键的曲子的话,有多少不同的曲子可以弹? - 输入
-
本题有多组数据,每组数据第一行为两个整数N和M(2 <= N <= 100, 1 <= M <= 500)。
- 输出
-
对于每组数据,输出不同的曲子数。(所有答案对1000000007取余)
- 样例输入
-
2 1 2 2
- 样例输出
-
4 8
- 提示
-
无
- 来源
-
XadillaX
参考了大神的代码才搞定 居然才明白这就是记忆化搜索
解题思路:用mat[k][i][j]记录弹了k个健后,停在了i行j列的位置上的弹法数,
* 那么状态转移方程就是mat[k][i][j]=sum{mat[k-1][a][b]}(a,b)为靠近(i,j)的* 四个位置,最后的答案就是sum{ mat[m][i][j] }(1<=i<=n,1<=j<=n)#include<stdio.h> #include<string.h> const int mod=1000000007; int n,m,a[2][150][150],step[4][2]={0,1,0,-1,1,0,-1,0}; int main() { int i,j,x,y; while(scanf("%d %d",&n,&m)!=EOF) { memset(a,0,sizeof(a)); for(i=1;i<=n;i++) for(j=1;j<=n;j++) a[0][i][j]=1; m--; for(int t=1;t<=m;t++) { for(i=1;i<=n;i++) for(j=1;j<=n;j++) for(int k=0;k<4;k++) { x=step[k][0]+i; y=step[k][1]+j; if(x>=1&&x<=n&&y>=1&&y<=n) a[1][i][j]=(a[1][i][j]+a[0][x][y])%mod; } for(i=1;i<=n;i++) for(j=1;j<=n;j++) { a[0][i][j]=a[1][i][j]; a[1][i][j]=0; } } int ans=0; for(i=1;i<=n;i++) for(j=1;j<=n;j++) ans=(ans+a[0][i][j])%mod; printf("%d\n",ans); } return 0; }
记忆化搜索:算法上依然是搜索的流程,但是搜索到的一些解用 动态规划的那种思想和模式作一些保存。一般说来,动态规划总要遍历所有的状态,而搜索可以排除一些无效状态。更重要的是搜索还可以剪枝,可能剪去大量不必要的状态,因此在空间开销上往往比动态规划要低很多。记忆化算法在求解的时候还是按着自顶向下的顺序,但是每求解一个状态,就将它的解保存下来,以后再次遇到这个状态的时候,就不必重新求解了。这种方法综合了搜索和动态规划两方面的优点,因而还是很有实用价值的。
宁波工程学院 1350 气坏了老虎乐坏了兔 记忆化搜索 帅呆了
最新推荐文章于 2024-05-11 09:21:20 发布