zoukankan      html  css  js  c++  java
  • poj 1088

    问题: 找给定的图中最长下降路线的长度。

    分析:可以看作dfs中的广义连通(高度作为连通的判断条件),对每个点都考虑它的连通的长度,此外,找某个点的连通长度时会有对其他点的连通长度单向调用(状态转移,dp),可以记录下来(记忆化搜索)避免重复计算。

    实现:

     1 #include<iostream>
     2 #include<algorithm>
     3 using namespace std;
     4 const int maxn = 100+5;
     5 int h[maxn][maxn], r, c, mem[maxn][maxn] = {0};
     6 bool is_out(int x, int y)
     7 {
     8         return (x<0 || x>r - 1 || y<0 || y>c - 1)?true:false;
     9 }
    10 int ad_dfs(int x,int y) {
    11     int tempmax = 0, fri[4][2] = { {x - 1,y},{x + 1,y},{x,y - 1},{x,y+1} };
    12     for (int i = 0; i < 4; i++)
    13     {
    14         int tx = fri[i][0];
    15         int ty = fri[i][1];
    16         if (is_out(tx,ty)||h[x][y]<=h[tx][ty])
    17             continue;
    18         else if(mem[tx][ty])
    19                 tempmax = tempmax<mem[tx][ty]?mem[tx][ty]:tempmax;
    20         else {    mem[tx][ty] = ad_dfs(tx, ty);tempmax = tempmax<mem[tx][ty] ? mem[tx][ty] : tempmax;}
    21     }
    22     return mem[x][y]=tempmax+1;
    23 }
    24 int main()
    25 {
    26     //freopen("in.txt", "r", stdin);
    27     //freopen("out.txt", "w", stdout);
    28     cin >> r >> c;
    29     for (int i = 0; i < r; i++)
    30         for (int j = 0; j < c; j++)
    31             cin >> h[i][j];
    32     int maxlen = 0;
    33     for (int i = 0; i < r; i++)
    34         for (int j = 0; j < c; j++)
    35         {
    36             ad_dfs(i,j);
    37             maxlen = maxlen < mem[i][j] ? mem[i][j]:maxlen;
    38         }
    39     printf("%d
    ",maxlen);
    40     return 0;
    41 }
    View Code

    优化:减少不必要的中间量,if else 逻辑仅取成立,仅取在界内。

    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int maxn = 100+5;
    int h[maxn][maxn], r, c, mem[maxn][maxn] = {0};
    bool is_in(int x, int y){    return (x > -1 && x<r&& y>-1 && y < c);}
    int ad_dfs(int x,int y) {
        //优化后
        int fri[4][2] = { {x - 1,y},{x + 1,y},{x,y - 1},{x,y+1} };
        for (int i = 0; i < 4; i++)
        {
            int tx = fri[i][0], ty = fri[i][1];
            if (is_in(tx, ty)&&h[tx][ty]<h[x][y])
                if(mem[tx][ty]) mem[x][y]= mem[x][y]<mem[tx][ty]+1 ? mem[tx][ty]+1 : mem[x][y];
                    else { mem[tx][ty] = ad_dfs(tx, ty); mem[x][y] = mem[x][y]<mem[tx][ty] + 1 ? mem[tx][ty] + 1 : mem[x][y];}
        }
        return mem[x][y];
    }
    int main()
    {
        //freopen("in.txt", "r", stdin);
        //freopen("out.txt", "w", stdout);
        cin >> r >> c;
        for (int i = 0; i < r; i++)
            for (int j = 0; j < c; j++)
                cin >> h[i][j];
        int maxlen = 0;
        for (int i = 0; i < r; i++)
            for (int j = 0; j < c; j++)
            {
                mem[i][j]=ad_dfs(i,j);
                maxlen = maxlen < mem[i][j] ? mem[i][j]:maxlen;
            }
        cout<<maxlen+1<<endl;
        return 0;
    }
    View Code

    小结:dfs的深入和dp,记忆化简化。初始化目标状态后,之后状态改变(当且仅当存在单向高度差).

  • 相关阅读:
    多输出感知机及其梯度
    《机器学习实战》-线性回归
    《机器学习实战》-逻辑(Logistic)回归
    SQL Server 空间监测
    SQL Server 从数据库快照还原数据库
    SQL Server 创建数据库快照
    SQL Server 数据库的自动选项
    SQL Server 数据库游标选项
    SQL Server 数据库状态选项
    MYSQL 二进制还原
  • 原文地址:https://www.cnblogs.com/paulzjt/p/5620283.html
Copyright © 2011-2022 走看看