当青训营遇上码上掘金
前言与声明:
本文用来记录本人做的主题活动,若读者认为对自己有帮助的话不妨在阅读结束之后点赞评论。
如果有任何问题或建议,可以在留言处指出,也欢迎大家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…
喜欢的话不妨点个赞再走吧,也欢迎关注。