码迷,mamicode.com
首页 > 其他好文 > 详细

hdu--1978--记忆化深度搜索||递推

时间:2014-08-07 18:30:31      阅读:277      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   io   数据   for   

这题 我开始的做法是 记忆化搜索  但是tm地竟然tle了。。。很想不通 因为数据很小啊 就100 虽然方案的总数可能会很大..

然后 我就去百度 记忆化搜索 看下是不是我用错方法了 事实证明 我虽然没有用错 但还是 学到了很多=-=、

其实  我很早以前 也看过关于 记忆化搜索的一些介绍 但是 并没有太多感觉 并不是那些作者写的不好 而是我的水平没到 感受不了。。

很多东西会在不知不觉中提升~

我想 将我读的这篇介绍 传到这篇博客里来 似乎只能上传照片和视频=-=   那我给个链接吧  传送

虽然里面的代码不是用C/C++写的 但其实不会太影响我们的阅读 重点是对于 动态规划 与 搜索思想的理解

------------touch  me

然后 我继续回过头来检查自己的TLE代码 我去discuss里看了下别人的讨论 发现很多人用的都是 递推式的动态规划做的 看到了一个和我用相同的记忆化深搜做的

and then  i got it

我对于maze[i][j]的处理太懒了...耗了太多时间..

我将tle与改后AC代码都放上来吧

bubuko.com,布布扣
 1 #include <iostream>
 2 #include <cstring>
 3 using namespace std;
 4 
 5 int n , m;
 6 const int mod = 10000;
 7 const int size = 110;
 8 int maze[size][size];
 9 int dp[size][size];
10 bool vis[size][size];
11 
12 int dfs( int x , int y )
13 {
14     if( x==n && y==m )
15         return 1;
16     if( vis[x][y] )
17         return dp[x][y];
18     if( maze[x][y]==0 )
19         return 0;
20     for( int i = x ; i<=n ; i++ )
21     {
22         for( int j = y ; j<=m ; j++ )
23         {
24             if( (i-x + j-y) > maze[x][y] || x==i && y==j )
25                 continue;
26             else
27             {
28                 dp[x][y] += dfs(i,j);
29                 if( dp[x][y]>=mod )
30                     dp[x][y] %= mod;
31             }
32         }
33     }
34     vis[x][y] = true;
35     return dp[x][y];
36 }
37 
38 int main()
39 {
40     cin.sync_with_stdio(false);
41     int t , ans;
42     while( cin >> t )
43     {
44         while( t-- )
45         {
46             memset( vis , false , sizeof(vis) );
47             memset( dp , 0 , sizeof(dp) );
48             cin >> n >> m;
49             for( int i = 1 ; i<=n ; i++ )
50             {
51                 for( int j = 1 ; j<=m ; j++ )
52                 {
53                     cin >> maze[i][j];
54                 }
55             }
56             ans = dfs(1,1);
57             cout << ans << endl;
58         }
59     }
60     return 0;
61 }
View Code

*** 其实 vis数组 是可以不写的 因为完全可以通过if( dp[ x ] [ y ])return dp[x][y]来做到 但是我习惯上 有时候会写上它 有助于理解

bubuko.com,布布扣
 1 #include <iostream>
 2 #include <cstring>
 3 using namespace std;
 4 
 5 int n , m;
 6 const int mod = 10000;
 7 const int size = 110;
 8 int maze[size][size];
 9 int dp[size][size];
10 bool vis[size][size];
11 
12 int dfs( int x , int y )
13 {
14     if( x==n && y==m )
15         return 1;
16     if( vis[x][y] )
17     {
18         return dp[x][y];
19     }
20     if( maze[x][y]==0 )
21         return 0;
22     for( int i = 0 ; i<=maze[x][y] ; i++ )
23     {
24         for( int j = 0 ; j+i<=maze[x][y] ; j++ )
25         {
26             if( !(i+j) || x+i>n || y+j>m )
27                 continue;
28             else
29             {
30                 dp[x][y] += dfs( x+i,y+j);
31                 if( dp[x][y]>=mod )
32                     dp[x][y] %= mod;
33             }
34         }
35     }
36     vis[x][y] = true;
37     return dp[x][y];
38 }
39 
40 int main()
41 {
42     cin.sync_with_stdio(false);
43     int t , ans;
44     while( cin >> t )
45     {
46         while( t-- )
47         {
48             memset( vis , false , sizeof(vis) );
49             memset( dp , 0 , sizeof(dp) );
50             cin >> n >> m;
51             for( int i = 1 ; i<=n ; i++ )
52             {
53                 for( int j = 1 ; j<=m ; j++ )
54                 {
55                     cin >> maze[i][j];
56                 }
57             }
58             ans = dfs(1,1);
59             cout << ans << endl;
60         }
61     }
62     return 0;
63 }
View Code

 

稍微 解释下 有助于 初学者的我们来理解:

因为是 深搜 所以这是递归的 我们可以将dp[ x ] [ y ]看成在N * M的地图里有多少种方式从(N,M)这个终点走到(X,Y)这个点 然后你可能会遇到dp[ x1 ] [ y1 ]与dp[ X2 ][ y2]都需要求得dp[ x3 ][ y3 ]那么我们只要将这个值给保存下来 在(x1,y1),(x2,y2)需要的时候 直接给它们就可以了 这里就有着DP对于重叠子问题的处理 而递归又是深搜的体现

这里 有一个边界注意下 就是(N,M) 当你搜索到这个点时 就可以看成是 递归出口了 然后直接返回一个 1 就可以了

 

我们再来讲下 递推的处理

这就和递归 完全2个方向 可以这样想 一个是 自底向上 一个是顶向下 dp[ x ][ y ]就变成了是N*M的地图里有多少种方式从(1,1)走到(x,y)这个点

其余多的解释 我也讲不来了 并且 我不确认 我以上所讲 都是正确的 都是我自己的理解 欢迎 探讨=-=

bubuko.com,布布扣
 1 #include <iostream>
 2 #include <cstring>
 3 using namespace std;
 4 
 5 const int size = 110;
 6 const int mod = 10000;
 7 int maze[size][size];
 8 int dp[size][size];
 9 
10 int main()
11 {
12     cin.sync_with_stdio(false);
13     int n , m , t;
14     while( cin >> t )
15     {
16         while( t-- )
17         {
18             cin >> n >> m;
19             for( int i = 1 ; i<=n ; i++ )
20             {
21                 for( int j = 1 ; j<=m ; j++ )
22                 {
23                     cin >> maze[i][j];
24                 }
25             }
26             memset( dp , 0 , sizeof(dp) );
27             dp[1][1] = 1;
28             for( int i = 1 ; i<=n ; i++ )
29             {
30                 for( int j = 1 ; j<=m ; j++ )
31                 {
32                     for( int p = 0 ; p<=maze[i][j] ; p++ )
33                     {
34                         for( int q = 0 ; p+q<=maze[i][j] ; q++ )
35                         {
36                             if( !(p+q) || p+i>n || q+j >m )
37                                 continue;
38                             else
39                             {
40                                 dp[i+p][j+q] += dp[i][j];
41                                 if( dp[i+p][j+q]>=mod )
42                                     dp[i+p][j+q] %= mod;
43                             }
44                         }
45                     }
46                 }
47             }
48             cout << dp[n][m] <<endl;
49         }
50     }
51     return 0;
52 }
View Code

其实我觉得 刚接触dfs的时候 并不是那么容易理解 或者 像我这种迟钝点的 我写了下面一段小小的代码 有助于理解=-=

bubuko.com,布布扣
#include <iostream>
using namespace std;

void dfs( char ch,int x )
{
    char zh = ch + 1;
    x+=2;
    for( int i = x ; i<=10 ; i+=2 )
    {
        cout << ch << " " << i << endl;
        dfs(zh,i);
    }
}

int main()
{
    dfs(a,1);
}
View Code

 

 

today:

  在虎扑看到了个很有感触的帖子...选了里面一些jr的回帖 当做today:

  和前女友异地恋,她经常主动打电话给我,有一天我嫌烦了,就对她说以后没事少给我打电话。她委屈地对我说:“想到你一个人在外地工作,身边一个朋友都没有,一个人吃饭,住房,我就很心疼,所以才老打电话给你。“

      和她分手快半年了,刚收到她的短信,想到和她过往,泪流满面
 
  在一起的那天:“哪怕你一辈子是小职员,我也会和你走下去。”
  分手的那天:“我觉得我十年后肯定不是这样,但是你十年后还是现在这个样子。”
  每天一点点努力,就是不想让下一个女人再说这种话。
 
  我不喜欢你抽烟,抽烟对身体不好又臭,如果你真的忍不住想抽烟的话就亲我。”现在想起,一幕幕仿佛昨天~~现在,只能祝她幸福了。
 
大一在网吧:
她:“在网吧?有件事想和你说。”
我:“现在没空,晚上回你。“
大二在宿舍:
她:“在睡觉呢?今天没点名,不过明天早上上课把你的看电影带过来给我看看好吗?”
我:“哦,明天有课?”
第二天继续睡觉。。。
大三夜里失眠:
我短信:“我还有机会吗?”
她回复:“黄花菜都凉了!”
毕业一年:
她:“我下月结婚,你能来吗?”
我:“这几个月在外派啊,估计赶不回来。”
毕业两年:
她:“帮我给宝宝取个名字吧,男孩。”
我:“哈,读书少,不会取啊。大宝?”
她:“你个弱智,永远不上心。”
啪,挂掉。

bubuko.com,布布扣 bubuko.com,布布扣


大哥们,我承认我当初比较混蛋,更多的是她是女神,我是穷小子,想得多,自卑。当黄花菜凉的时候人家就已经有男朋友了,你们想让我怎么办,去挖墙脚吗?我一直知道自己辜负了她,所以更不想去打扰她的生活,至于之后的交流也更多的是朋友之间的互动。
另外,当初有点文艺,快临产的时候她知道是个男孩,名字一直定不下来,所以问了下我,真没有其他的意思。
也奉劝JRS,凡事往前看,有好女孩要大胆追、要珍惜。记事起就哭过有数的四次,黄花菜就是其中之一!
 
我去找你。异地恋(不远),她几乎每个礼拜五都跟我说这句话,分手一年多我还是很难过的。
 
和前女友一起逛超市 她看到一盒巧克力很想买 拿起来又放下 
纠结了一会儿 最后说:算了不买了 好几十块钱 能给你买好多鸡翅吃呢。。。
现在想起来这句话还是很心酸 
最后也没有和她走到一起 还伤害了她 我真他妈是畜生
 

 

hdu--1978--记忆化深度搜索||递推,布布扣,bubuko.com

hdu--1978--记忆化深度搜索||递推

标签:style   blog   http   color   os   io   数据   for   

原文地址:http://www.cnblogs.com/radical/p/3897412.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!