欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

hdu2067 简单dp或者记忆化搜索

发布时间:2025/6/17 编程问答 33 豆豆
生活随笔 收集整理的这篇文章主要介绍了 hdu2067 简单dp或者记忆化搜索 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

题意:


小兔的棋盘

Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 6193 Accepted Submission(s): 3373


Problem Description 小兔的叔叔从外面旅游回来给她带来了一个礼物,小兔高兴地跑回自己的房间,拆开一看是一个棋盘,小兔有所失望。不过没过几天发现了棋盘的好玩之处。从起点(0,0)走到终点(n,n)的最短路径数是C(2n,n),现在小兔又想如果不穿越对角线(但可接触对角线上的格点),这样的路径数有多少?小兔想了很长时间都没想出来,现在想请你帮助小兔解决这个问题,对于你来说应该不难吧!
Input 每次输入一个数n(1<=n<=35),当n等于-1时结束输入。
Output 对于每个输入数据输出路径数,具体格式看Sample。
Sample Input 1 3 12 -1
Sample Output 1 1 2 2 3 10 3 12 416024



思路:
       简单dp, 因为是求最短,所以当前状态只能由上面或者左面过来(上半部分三角形),由于不能过对角线,我们可以只求一半,也就是上面三角形,最后乘2就行了,直接dp打表,或者记忆化搜索,对于记忆化搜索也可以1边记忆化搜索打表,就是最后在转换矩阵,终点变成了起点,起点变终点什么的,不难,我下面的是dp打表,和直接记忆化搜索的代码,记忆化搜索打表的没写,想写的直接在记忆或搜索的那个改改就行了。


dp

#include<stdio.h> #include<string.h> __int64 dp[40][40] = {0};void solve(int n) {dp[1][1] = 1;for(int i = 1 ;i <= n ;i ++)for(int j = i ;j <= n ;j ++){ if(i == 1 && j == 1) continue;dp[i][j] = dp[i][j-1] + dp[i-1][j];} }int main () {int n ,cas = 1;solve(36);while(~scanf("%d" ,&n) && n != -1){printf("%d %d %I64d\n" ,cas ++ ,n ,dp[n+1][n+1] * 2);}return 0; }

记忆化搜索


#include<stdio.h> #include<string.h> int mark[40][40]; __int64 dp[40][40]; int n;__int64 DFS(int x ,int y) {if(x == n + 1 && y == n + 1) return 1;if(mark[x][y]) return dp[x][y];__int64 sum = 0;if(x + 1 <= n + 1 && x + 1 <= y)sum += DFS(x + 1 ,y);if(y + 1 <= n + 1)sum += DFS(x ,y + 1);mark[x][y] = 1;dp[x][y] = sum;return sum; }int main () {memset(mark ,0 ,sizeof(mark));int cas = 1;while(scanf("%d" ,&n) && n != -1){memset(mark ,0 ,sizeof(mark));printf("%d %d %I64d\n" ,cas ++ ,n ,DFS(1 ,1) * 2);}return 0; }

总结

以上是生活随笔为你收集整理的hdu2067 简单dp或者记忆化搜索的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。