zoukankan      html  css  js  c++  java
  • 递推与记忆化搜索

     内容参考书籍《算法竞赛入门到进阶》

    先看一道经典题:poj1163 http://poj.org/problem?id=1163

     如果此题按照从上往下的方法计算,每走一步下一步就有2种选择,其复杂度为2n

    那么我们从下往上算,下面给出dfs代码:

    int dfs(int i,int j)
    {
    	if (i == n) return a[i][j];//递归到最后一行返回
    	return dp[i][j] = max(dfs(i+1,j),dfs(i+1,j+1))+ a[i][j];
    }

    从1,1开始往下走,一直到最后一行,返回,每一次取能走到该点的最大值加上该点,继续返回,代码很好理解,只是复杂度为2n

    下面我们再来讲一下递推,代码如下:

      for (int j = 1; j <= n; ++j) dp[n][j] = a[n][j];
      for (int i = n-1; i >= 1; --i)
      {
        for (int j = 1; j <= i; ++j)     {   dp[i][j] = max(dp[i+1][j],dp[i+1][j+1]) + a[i][j];     }
      }   cout<<dp[1][1]<<endl;

    首先是第一层循环,将三角形最下面一层全部赋值给dp,然后从下往上求解,输出dp[1][1]即是最大值。这样复杂度便只有n2

    那么搜索可以做到吗?当然可以,这就是我们说的记忆化,只需要在搜索算法中加入if即可,代码如下:

    int dfs(int i,int j)
    {
    	if (i == n) return a[i][j];//递归到最后一行返回
    	if (dp[i][j] >= 0) return dp[i][j];//记忆
    	return dp[i][j] = max(dfs(i+1,j),dfs(i+1,j+1))+ a[i][j];
    }
    

     这样搜索算法的复杂度也降到了n2,为什么要加这样一句话呢?我们可以发现,当我们从第2层的“3”往下走会经过“1”,计算一次从1出发的递归;从第2层的“8”往下走也会经过“1”,又重新计算了“1”出发的递归,为了避免这样的重复,使用记忆化便能避免,从而降低复杂度。

  • 相关阅读:
    Tomcat线程参数
    CDH平台规划注意事项
    python 不同数据类型的序列化
    Python 中__new__方法详解及使用
    线程生命周期
    如何在JAVA中每隔一段时间执行一段程序
    手动开启是事务提交回滚
    MySQL数据类型转换函数CAST与CONVERT的用法
    mybatis插入是返回主键id
    解决dubbo注册zookepper服务IP乱入问题的三种方式
  • 原文地址:https://www.cnblogs.com/125418a/p/12943702.html
Copyright © 2011-2022 走看看