当青训营遇上码上掘金 | 后端主题

104 阅读2分钟

当青训营遇上码上掘金

~~此文补上之前的活动,绝不是为了所谓的青豆。~~这里选择的是后端,题目为主题3和主题4。

  • 主题3:寻友之旅

小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K (0≤N , K≤100 000),并且小码在自己家原地不动等待小青。小青有两种交通方式可选:步行和公交。 步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1 公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走)

请帮助小青通知小码,小青最快到达时间是多久?

输入: 两个整数 N 和 K 输出: 小青到小码家所需的最短时间(以分钟为单位)

通过观察题目,我们可以知道该题数据范围较大,采用动态规划来解题,模拟小青在小马前方或后方的情况,并进行逐步解题。

比较难以理解的是最后一步,最节省时间的走法很可能是要搭公交车过小码家一段距离的,因此也需要在最后的答案进行相对应的比较求解。

const int N = 100005;

int n, k, dp[N], ans = INT_MAX;

int main() {
	cin >> n >> k;
	dp[n] = 0;
…		if (i >= k){
			ans = min(ans, dp[i] + i - k);
		}
	}
	cout << dp[k] << endl;
	return 0;
}
  • 主题 4:攒青豆

    现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)

    这道题目是经典题,同样适用动态规划解法,相对比较简单。

void solve() {
    vector <int> h = {5, 0, 2, 1, 4, 0, 1, 0, 3};
    int n = h.size(), ans = 0;
    vector<int> max_l(n), max_r(n);
    if (n == 0) {
    	return;
	}
    max_l[0] = h[0];
    for (int i = 1; i < n; ++i) {
        max_l[i] = max(max_l[i - 1], h[i]);
    }
    max_r[n - 1] = h[n - 1];
    for (int i = n - 2; i >= 0; --i) {
        max_r[i] = max(max_r[i + 1], h[i]);
    }
    for (int i = 0; i < n; ++i) {
        ans += min(max_l[i], max_r[i]) - h[i];
    }
	cout << ans << endl;
    return;
}

先从左开始扫描,再从右开始扫描,得出每个柱子左右最低的墙高度,最后在根据得出的数据将左右最低高度减去该位置柱子高度即可得到每个位置的青豆数量,再逐一加起来。

代码链接如下:

【主题创作_主题3:寻友之旅】code.juejin.cn/api/raw/719…

【主题4:攒青豆】code.juejin.cn/api/raw/719…

创作不易,水平有限。各位客官随意~