当青训营遇上码上掘金 | 主题创作活动

212 阅读1分钟

当青训营遇上码上掘金


前言与声明:

本文用来记录本人做的主题活动,若读者认为对自己有帮助的话不妨在阅读结束之后点赞评论。

如果有任何问题或建议,可以在留言处指出,也欢迎大家hack我的代码。

如果


主题 3:寻友之旅

通过阅读题目,可以发现很明显的状态转移,于是我们想用动态规划的思想来解决该问题。

由于数据范围是1e5的,所以理论上我们最大只能采用O(NlogN)的时间复杂度。

状态:dp[i]为从n到i的最短时间

参考代码如下:

const int N = 100010;
int n, k, dp[N], ans = INT_MAX;
inline void solve(){
    cin >> n >> k;
	dp[n] = 0;
	for (int i = n - 1; i >= 0; i--){
		dp[i] = dp[i + 1] + 1;
	}
	for (int i = n + 1; i <= N - 1; i++){
		int cur_w = dp[i - 1] + 1, cur_b = dp[i / 2] + 1;
		if (i % 2 != 0){
			cur_b = min(dp[(i + 1) / 2], dp[(i - 1) / 2]) + 2;
		}
		dp[i] = min(cur_w, cur_b);
		if (i >= k){
			ans = min(ans, dp[i] + i - k);
		}
	}
	cout << dp[k] << endl;
    return;
}

当然,也可以使用BFS或者Dijkstra来做这道题目,这里就不详细给出具体代码了。


主题 4:攒青豆

这是一道非常经典的题目,动态规划、单调栈或双指针都可解。

下面是动态规划解法:

顺着扫一遍,逆着扫一遍,每次更新一下从左/右开始的最大高度

然后再顺着扫一遍更新ans即可,O(N)时间复杂度。

题目中并没有给出数据范围,用该方法可以过1e8以内的数据, 接近1e8的数据可能需要使用快读或者关闭流同步的方法来进行常数优化, 或者直接开启O2 or O3优化。

代码如下:

inline 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/pen/7188088…

【主题创作_主题4:攒青豆】code.juejin.cn/pen/7188112…

喜欢的话不妨点个赞再走吧,也欢迎关注。