题目链接:https://www.luogu.com.cn/problem/P1508
大致题意是:给定(n,m)的矩阵,m为奇数,从最小面的中间位置开始往上走,只能走到左上方、上方、右上方的位置,直到走到第一行为止,问最多能获得多少分(即路径上的值只和最大)。解决方案就是记忆化搜索,要注意边界条件,就是第一行的最优值就是给定序列对应位置的值。代码如下:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef unsigned int ui; 4 typedef long long ll; 5 typedef unsigned long long ull; 6 #define pf printf 7 #define mem(a,b) memset(a,b,sizeof(a)) 8 #define prime1 1e9+7 9 #define prime2 1e9+9 10 #define scand(x) scanf("%llf",&x) 11 #define f(i,a,b) for(int i=a;i<=b;i++) 12 #define scan(a) scanf("%d",&a) 13 #define dbg(args) cout<<#args<<":"<<args<<endl; 14 #define pb(i) push_back(i) 15 #define ppb(x) pop_back(x) 16 #define inf 0x3f3f3f3f 17 #define maxn 1005 18 int n,m,t,ans=-inf,vis[maxn][maxn],dp[maxn][maxn],a[maxn][maxn];//dp[i][j]:从(i,j)位置出发得到的最大分数 19 int dfs(int x,int y) 20 { 21 if(vis[x][y])return dp[x][y]; 22 vis[x][y]=true; 23 int xx,yy,res=-inf; 24 f(i,-1,1) 25 { 26 xx=x-1; 27 yy=y+i; 28 if(xx<1||xx>n||yy<1||yy>m)continue; 29 res=max(res,dfs(xx,yy)+a[x][y]); 30 } 31 return dp[x][y]=res; 32 } 33 int main() 34 { 35 //freopen("input.txt","r",stdin); 36 //freopen("output.txt","w",stdout); 37 std::ios::sync_with_stdio(false); 38 scan(n); 39 scan(m); 40 f(i,1,n) 41 f(j,1,m) 42 { 43 scan(a[i][j]); 44 } 45 mem(vis,false); 46 f(i,1,m) 47 { 48 dp[1][i]=a[1][i]; 49 vis[1][i]=true; 50 } 51 dfs(n+1,m/2+1);//得出(n+1,m/2+1)上面三个位置的最优值 52 // ans=max(max(dp[n][m/2],dp[n][m/2+1]),dp[n][m/2+2]); 53 pf("%d",dp[n+1][m/2+1]); 54 }