每日一题-跳跃题解(蓝桥杯)(动态规划)
Posted 行码棋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了每日一题-跳跃题解(蓝桥杯)(动态规划)相关的知识,希望对你有一定的参考价值。
分析:这是一道标准的动态规划题。
首先需要弄清两个方面:
- 状态表示:
g [ i ] [ j ] g[i][j] g[i][j] 表示到达此点的最大权值。 - 状态转移方程:
a n s = m a x ( a n s , g [ i + X [ k ] ] [ j + Y [ k ] ] ) ans = max(ans,g[i+X[k]][j+Y[k]]) ans=max(ans,g[i+X[k]][j+Y[k]])表示求能够到达此点的所有点的权值最大值。
g [ i ] [ j ] + = a n s g[i][j] += ans g[i][j]+=ans表示最后更新该点的权值
注意:因为点是从前往后更新的,所以每步都在获取局部最优解,当上一个点到达该点时,上一个点一定是最优的,故只需要进行一次的点的权值更新。
代码解释:
X[],Y[]
数组代表的是该点可以访问到点的坐标的一个变化值。数组大小为9
则是该点可以访问到九个点
(
i
+
X
[
k
]
,
j
+
Y
[
k
]
)
(i+X[k],j+Y[k])
(i+X[k],j+Y[k])代表的是将要访问的点的坐标
(
x
,
y
)
(x,y)
(x,y),x
和y
的坐标同时变化,就可以模拟访问访问其它点了,也就是访问其他点是通过设置X[],Y[]
数组来实现的。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e3+5;
int g[105][maxn];
ll n,m;
int X[9]=0,0,0,-1,-1,-1,-2,-2,-3;
int Y[9]=-3,-2,-1,-2,-1,0,-1,0,0;
int main()
// 请在此输入您的代码
cin >> n >> m;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
cin>>g[i][j];
int ans = INT_MIN;
for(int k = 0; k < 9; k++)
if(i + X[k] >= 1 && j + Y[k] >= 1)
ans = max(ans, g[i + X[k]][j + Y[k]]);
if(ans != INT_MIN) g[i][j] += ans;
cout << g[n][m] << '\\n';
return 0;
2023.01.28更新:评论中有人说坐标变换为什么都是负的,没有正的,具体可以看下评论回复,下面我写一版正着转移的代码。因为这篇题解是很久之前写的了,现在看来代码不是很好看,不过暂且放那了。
下面代码仅在上述链接评测正确,并不代表是对的,思路大家可以参考。
#include<bits/stdc++.h>
using namespace std;
const int dx[] = 0, 0, 0, 1, 1, 1, 2, 2, 3;
const int dy[] = 3, 2, 1, 2, 1, 0, 1, 0, 0;
int main()
int n, m;
cin >> n >> m;
vector<vector<int>> f(n + 1, vector<int>(m + 1, -1e9)), g(f);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
cin >> g[i][j];
f[1][1] = g[1][1];
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
for(int k = 0; k < 9; k++)
if(i + dx[k] > n || j + dy[k] > m) continue;
int val = f[i][j] + g[i + dx[k]][j + dy[k]];
f[i + dx[k]][j + dy[k]] = max(f[i + dx[k]][j + dy[k]], val);
cout << f[n][m] << "\\n";
return 0;
以上是关于每日一题-跳跃题解(蓝桥杯)(动态规划)的主要内容,如果未能解决你的问题,请参考以下文章