zoukankan      html  css  js  c++  java
  • dfs+dp思想的结合------hdu1078

    首先是题目的意思:

    从一个正方形的0,0点开始走,只能横着走,竖着走,最多走k步,下一个点的数一定要比当前这个点的值大,每走一步,就加上下一个点的数据,问数据最大能有多少。

    首先遇到这种题目,走来走去的,一开始想到的是搜索,但是搜索我们搜的很多是路径,能走到那个点的最短路,但是这道题目不一样。

    首先要注意的一点是,如果没有条件的搜索,那就是枚举。只有搜遍了才能得到最后的解。

    1s题,只是搜的话肯定TLE了。

    所以我们想到的自然就是dp了。dp的好处是什么?就是能减少不必要的搜索。用已知的结果减少当前路径搜索的时间。

    几个要点:

    1、只能从0,0开始走,所以已经减少了很多复杂了,不要傻乎乎的全部循环。

    2、注意dfs时候的边界判断。

    3、更新值时不要忘记加上当前自己的值。

    状态转移方程

    dp[][] = max(所有可以从当前点走到的点的dfs的结果集)

    初始值肯定是0没问题

    最后dp【0】【0】就是结果了。

    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    /*dfs+dp,hdu1078*/
    
    int maps[105][105];//用来保存原数据
    int dp[105][105];//dp数组
    int k;//最多走的步数
    int n;//区域大小
    
    int update(int x,int y)
    {
        int i,j;
        int fromX,toX;
        int fromY,toY;
        int maxTemp=0;
        int temp;
    
        //判断边界条件
        if(dp[x][y])
            return dp[x][y];
    
        if(x-k < 0)
            fromX = 0;
        else
            fromX = x-k;
    
        if(x+k >= n)
            toX = n-1;
        else
            toX = x+k;
    
        if(y-k < 0)
            fromY = 0;
        else
            fromY = y-k;
    
        if(y+k >= n)
            toY = n-1;
        else
            toY = y+k;
    
        for (i = fromX; i <= toX; i++)
        {
            if(i!=x && maps[i][y] > maps[x][y])
            {
                temp = update(i,y);
                if(temp > maxTemp)
                    maxTemp = temp;
            }
        }
    
        for (j = fromY; j <= toY; j++)
        {
            if(j!=y && maps[x][j] > maps[x][y])
            {
                temp = update(x,j);
                if(temp > maxTemp)
                    maxTemp = temp;
            }
        }
    
        dp[x][y] = maxTemp + maps[x][y];
        return dp[x][y];
    }
    
    
    int    main()
    {
        int i,j;//循环变量
        int maxNumber=0;//记录结果
    
        while (true)
        {
            cin>>n>>k;
            if(n==-1 && k==-1)
                break;
            memset(dp,0,sizeof(dp));
            //输入数据
            for (i = 0; i < n; i++)
                for (j = 0; j < n; j++)
                    cin>>maps[i][j];
    
            //只能从0.0点开始走
            maxNumber = update(0,0);
    
            cout<<maxNumber<<endl;
        }
        
        return 0;
    }
  • 相关阅读:
    平衡二叉树之RB树
    平衡二叉树之AVL树
    实现哈希表
    LeetCode Median of Two Sorted Arrays
    LeetCode Minimum Window Substring
    LeetCode Interleaving String
    LeetCode Regular Expression Matching
    PAT 1087 All Roads Lead to Rome
    PAT 1086 Tree Traversals Again
    LeetCode Longest Palindromic Substring
  • 原文地址:https://www.cnblogs.com/linkstar/p/5380816.html
Copyright © 2011-2022 走看看