zoukankan      html  css  js  c++  java
  • 记忆化搜搜

    例一:求到终点的路径条数

    思路:

    深搜的时候是从vis[1][1]开始搜的,第一次直搜到vis[n][n],然后返回的时候可以得到vis[n-1][n-2]那个点的路,当第二次搜到vi[n-1][n-2]这个点的时候就不用往下搜了, 直接加上在这个点的路。

    代码:

    lld dfs(int x, int y) {

             if (vis[x][y] != 0) return vis[x][y]; //如果改点已搜过,直接返回结果即可

             if (x == n && y == n) return 1;

             for (int i = 0; i < 4; ++i) {

                       int nx = x + go[i][0];

                       int ny = y + go[i][1];

                       if (maze[nx][ny] != -1 && dist[nx][ny] < dist[x][y]) {

                                vis[x][y] += dfs(nx, ny);

                       }

             }

             return vis[x][y];

    }

    若没有使用记忆优化:

    void dfs(int x,int y){

        int sx,sy,i;

        if(x==n&&y==n){

            tot++;//tot记录能够到达终点的路的条数

            return;

        }

        for(i=2;i<4;i++){

            sx=x+dir[i][0],sy=y+dir[i][1];

            if(sx>n||sy>n) continue;

            if(dis[sx][sy]>=dis[x][y]) continue;

            dfs(sx,sy);

        }

    }

    例二:求不同的排列数

    题意:用A~Z代替1~26,问一串数字有多少不同的译码种数。

    关键:若下一位不为0,本位可以拆分出来则 ret += dfs(x + 1);。若本位和下一位不超过26,且再后面的一位不为0,则这两位可以拆分出来则 ret += dfs(x + 2);。

    代码:

    lld dfs(int s, int e) {

             if (s >= e) return 1;

             if (dp[s] > 0) return dp[s];

             int t1 = str[s] - '0';

             int t2 = str[s + 1] - '0';

             if (t2 != 0) dp[s] += dfs(s + 1, e);

             if (t1 * 10 + t2 <= 26 && str[s + 2] != '0') //只剩最后两位的时候可以再计算一次

                       dp[s] += dfs(s + 2, e);

             return dp[s];

    }

    练习:

    师弟

  • 相关阅读:
    bootstrap 辅助类
    bootstrap 表单类
    bootstrap 图片类 和 按钮类 部分
    angularJs学习笔记-入门
    react-conponent-todo
    react-conponent-secondesElapsed
    react-conponent-hellocynthia
    react学习笔记1
    1970年// iPhone “变砖”后可继续正常使用的解决方案
    23种设计模式
  • 原文地址:https://www.cnblogs.com/fripside/p/3592516.html
Copyright © 2011-2022 走看看