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;
    }
  • 相关阅读:
    浙江工业大学校赛 小马哥和数列
    浙江工业大学校赛 XiaoWei的战斗力
    浙江工业大学校赛 猜猜谁是我
    浙江工业大学校赛 竹之书(大数,同余定理)
    浙江工业大学校赛 画图游戏 BugZhu抽抽抽!!
    浙江工业大学校赛 画图游戏
    pta 天梯地图 (Dijkstra)
    Atom打造 c/c++编译环境(忙了一个上午)
    HRBUST
    CSU 1808 地铁 (Dijkstra)
  • 原文地址:https://www.cnblogs.com/linkstar/p/5380816.html
Copyright © 2011-2022 走看看