zoukankan      html  css  js  c++  java
  • [HDU] 1078 FatMouse and Cheese 稍微要变化一点的递增非连续子序列

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1078

    方法:由于该题目中是二维数组,并且每一个cell都可能被从几个方向探寻到,而不是一维的那样只会被从前往后的方向探寻到,所以,这里需要对这些cell(除起始点那个)根据里面含有的cheese量递增排序,然后根据这个顺序去考虑cell。可以这样理解,计算一个cell A作为当前递增非连续子序列最后一个元素时能获取多少的值,对于b,c ,d,e ....这些可以直接移动到a的cell,

    首先要计算出b,c ,d,e。。这些cell作为递增非连续子序列最后一个元素时能获取多少的值,这是他们的最优解,然后根绝这些最优解计算出cell A作为当前递增非连续子序列最后一个元素时能获取多少的值的最优解。该题目的最优子结构是这样的,如果不按排序后的顺序处理的话,那么在计算出cell A作为当前递增非连续子序列最后一个元素时能获取多少的值的时候,很有可能其子问题(b,c ,d,e。。这些cell作为递增非连续子序列最后一个元素时能获取多少的值)还没有计算出,这样就不满足最优子结构

    考虑一个cell作为当前递增非连续子序列最后一个元素的情况:从该cell开始,从4个方向水平或垂直的方向探寻值比该cell小的cell,看以这些cell作为递增非连续子序列最后一个元素时能获取多少chess,选择最大的一个和当前cell相加,得到当前cell作为当前递增非连续子序列最后一个元素时能获取多少的值,状态转移方程如下:

    F(current_cell) =cerrent_cell.quantity +max({F(cell)| current_cell can be reached from cell in the scope of 4 directions});

    最后结果,

    Max({F(cell)|all the cells });

    感谢:注意看清楚题目,题目要求老鼠移动的工程中不能转弯,要不就是水平要不就是垂直。

    代码:

    View Code
    #include<iostream>
    #include<math.h>
    #include<algorithm>
    #include<queue>
    using namespace std;
    int const MAX =0x3f3f3f3f;
    struct Cell
    {
        int x,y;
        int quantity;
    };
    struct matrixNode
    {
        int quantity;
        int sortIndex;
        int step;
        int x,y;
    };
    bool cmp(Cell x,Cell y)
    {
        if(x.quantity<y.quantity)
            return true;
        return false;
    }
    bool canGo(int x,int y,int n)
    {
        return x>=1 && x<=n && y>=1 && y<=n;
    }
    int direction[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
    
    int main()
    {
        int n, k;
        while(scanf("%d %d",&n,&k) && !(n==-1 && k==-1) )
        {
            Cell cells[10002];
            matrixNode matrix[101][101];
            bool v[101][101];
            int dp[10002];
            memset(dp,0,sizeof(dp));
             
            int c=1;
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                {
                    cells[c].x=i;
                    cells[c].y=j;
                    scanf("%d",&cells[c].quantity);
                    matrix[i][j].quantity = cells[c].quantity;
                    c++;
                }
            sort(cells+2,cells+c,cmp);
            for(int i=2;i<=n*n;i++)
                matrix[cells[i].x][cells[i].y].sortIndex=i;
            matrix[1][1].sortIndex=1;
            cells[0].y = cells[0].x = cells[0].quantity =0;
            dp[1] = cells[1].quantity;
            for(int i=2;i<=n*n;i++)
            {
                int max = -MAX;
                for(int xx=1;xx<=k;xx++)
                    for(int yy=0;yy<4;yy++)
                        if(canGo(cells[i].x+direction[yy][0]*xx,cells[i].y+direction[yy][1]*xx,n) && matrix[cells[i].x+direction[yy][0]*xx][cells[i].y+direction[yy][1]*xx].quantity <cells[i].quantity )
                            max = max < dp[  matrix[cells[i].x+direction[yy][0]*xx][cells[i].y+direction[yy][1]*xx].sortIndex ] ?  dp[  matrix[cells[i].x+direction[yy][0]*xx][cells[i].y+direction[yy][1]*xx].sortIndex ] :max;
                dp[i]=max+cells[i].quantity;
            }
            int max = -MAX;
            for(int i=1;i<=n*n;i++)
                max = max<dp[i] ? dp[i]:max;
            cout<<max<<endl;
        }
        return 0;
    } 
  • 相关阅读:
    先创建项目 后版本化的步骤
    EditorLineEnds.ttr 错误问题
    TStringList 的Sorted属性
    Delphi out 参数 string Integer
    unity 调整摄像机视角完整脚本
    unity windowEditor平台下鼠标左键控制摄像机的视角
    C# 哈希表HashTable的简单使用
    唯一分解定理
    费马小定理的证明
    树状数组--求逆序对个数
  • 原文地址:https://www.cnblogs.com/kbyd/p/3054132.html
Copyright © 2011-2022 走看看