首页 > 代码库 > UESTC 电子科大专题训练 DP-F

UESTC 电子科大专题训练 DP-F

UESTC 1271

题意:有一个n*m的地图,每个格子有一定数量的金子,如果是负数,说明是陷阱,将会失去金子,如果金子数小于0就会死掉,你可以往四个方向走,分别是:(x+1,y),(x,y+1),(x+1,y+2)(x+1,y),(x,y+1),(x+1,y+2)and(x+2,y+1问最多可以获得多少金子

思路:每一个格子最多可以通过4个方向到达,可推得递推式为 dp[i][j]=max(dp[i-1][j],dp[i][j-1],dp[i-1][j-2],dp[i-2][j-2])+g[i][j],但是注意在某个位置可能死掉,所以dp[i][j]为负数的位置要除开

AC代码:

#include "iostream"
#include "string.h"
#include "stack"
#include "queue"
#include "string"
#include "vector"
#include "set"
#include "map"
#include "algorithm"
#include "stdio.h"
#include "math.h"
#define ll long long
#define bug(x) cout<<x<<" "<<"UUUUU"<<endl;
#define mem(a) memset(a,0,sizeof(a))
#define mp(x,y) make_pair(x,y)
using namespace std;
const long long INF = 1e18+1LL;
const int inf = 1e9+1e8;
const int N=1e5+100;
const ll mod=1e9+7;

int g[1005][1005],dp[1005][1005],n,m;
int main(){
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    cin>>n>>m;
    for(int i=1; i<=n; ++i){
        for(int j=1; j<=m; ++j){
            cin>>g[i][j];
        }
    }
    int  ans=g[1][1];
    dp[1][1]=g[1][1];
    for(int i=1; i<=n; ++i){
        for(int j=1; j<=m; ++j){
            if(i==1 && j==1) continue;
            int r=-inf;
            if(i-1>0 && dp[i-1][j]>=0) r=max(r,dp[i-1][j]+g[i][j]);
            if(j-1>0 && dp[i][j-1]>=0) r=max(r,dp[i][j-1]+g[i][j]);
            if(i-1>0 && j-2>0 && dp[i-1][j-2]>=0) r=max(r,dp[i-1][j-2]+g[i][j]);
            if(i-2>0 && j-1>0 && dp[i-2][j-1]>=0) r=max(r,dp[i-2][j-1]+g[i][j]);
            dp[i][j]=r;
            ans=max(ans,dp[i][j]);
        }
    }
    cout<<ans<<endl;
    return 0;
}

 

UESTC 电子科大专题训练 DP-F