洛谷1508 简单记忆化搜索

题目链接: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  } 

猜你喜欢

转载自www.cnblogs.com/randy-lo/p/12389359.html