题意:有一个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; }
时间: 2024-12-16 10:36:00