zoukankan      html  css  js  c++  java
  • 小象和老鼠 DP

    小象和老鼠 DP

    (N*M)的网格图,格子((i,j))(A_{i,j})个老鼠,问小象从左上角((1,1))走到右下角((N,M))看到的最少老鼠。小象可以看见老鼠,当且仅当老鼠的位置((x2,y2))满足(|x1-x2|+|y1-y2|le1)

    比较有意思的一道DP题,还是比较简单。我们发现如果直接设(f[i][j])跑会导致一些格子重复计算,所以我们可以设(f[i][j][0])表示到位置((i,j))时最少看到的老鼠数量,并且当前状态是从上面转移而来的(f[i][j][1])表示到位置((i,j))时最少看到的老鼠数量,并且当前状态是从左面转移而来的,这样我们便可以获得决策所需要的全部条件,从而避免重复计算。

    转移方程看着图写就好了

    //f[i][j][0]当前状态从上面转移而来
    f[i][j][0]=min(f[i-1][j][1]+mp[i][j+1]+mp[i+1][j], f[i][j][0]);
    f[i][j][0]=min(f[i-1][j][0]+mp[i+1][j]+mp[i][j-1]+mp[i][j+1], f[i][j][0]);
    //f[i][j][0]当前状态从左面转移而来
    f[i][j][1]=min(f[i][j-1][1]+mp[i][j+1]+mp[i-1][j]+mp[i+1][j], f[i][j][1]);
    f[i][j][1]=min(f[i][j-1][0]+mp[i][j+1]+mp[i+1][j], f[i][j][1]);
    

    完整代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define MAXN 1010
    using namespace std;
    int f[MAXN][MAXN][2],mp[MAXN][MAXN];
    int n,m;
    int calc(int x, int y){
        int res=0;
        if(x+1>=1&&x+1<=n) res+=mp[x+1][y];
        if(x-1>=1&&x-1<=n) res+=mp[x-1][y];
        if(y+1>=1&&y+1<=m) res+=mp[x][y+1];
        if(y-1>=1&&y-1<=m) res+=mp[x][y-1];
        return res+mp[x][y];
    }
    int main(){
        scanf("%d %d", &n, &m);
        for(int i=0;i<=n;++i)
        for(int j=0;j<=m;++j)
            f[i][j][0]=f[i][j][1]=0x3f3f3f3f;
        for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j)
            scanf("%d", &mp[i][j]);
        f[1][1][0]=f[1][1][1]=calc(1, 1);
        for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j){
            //f[i][j][0]当前状态从上面转移而来
            f[i][j][0]=min(f[i-1][j][1]+mp[i][j+1]+mp[i+1][j], f[i][j][0]);
            f[i][j][0]=min(f[i-1][j][0]+mp[i+1][j]+mp[i][j-1]+mp[i][j+1], f[i][j][0]);
            //f[i][j][0]当前状态从左面转移而来
            f[i][j][1]=min(f[i][j-1][1]+mp[i][j+1]+mp[i-1][j]+mp[i+1][j], f[i][j][1]);
            f[i][j][1]=min(f[i][j-1][0]+mp[i][j+1]+mp[i+1][j], f[i][j][1]);
        }
        printf("%d", min(f[n][m][0], f[n][m][1]));
        return 0;
    }
    

    这是校内模拟赛做的一道题,一开始以为是道DP签到题导致思路都错了,后面静下心慢慢分析决策才想出正解,可见手推样例重要性。另外一定不要轻敌。

  • 相关阅读:
    jmeter录制rabbitmq消息-性能测试
    plsqll连接Oracle的两种方式
    Badboy录制脚本时,提示脚本错误的解决方法
    Decorator
    PyObject and PyTypeObject
    Python LEGB (Local, Enclosing, Global, Build in) 规则
    Python Namespace
    Method Resolve Order (MRO)
    Source Code Structure
    Bound Method and Unbound Method
  • 原文地址:https://www.cnblogs.com/santiego/p/11563826.html
Copyright © 2011-2022 走看看