小苯的格子移动
[题目链接](https://www.nowcoder.com/practice/d1c43a534cb943398e6fafcc5e27aefb)
思路
数轴上有 个格子,第
个格子的解锁时间为
(保证
)。从第 1 个格子出发,每秒可以移动到下一个格子(前提是已解锁)或原地等待。求到达第
个格子的最少时间。
贪心模拟
用 记录当前时间,初始为 0(在第 1 格)。依次考虑移动到第
格:
- 移动需要 1 秒,所以最早到达时间为
;
- 同时第
格需要在
时刻后才能到达。
因此到达第 格的最早时间为:
$$
这是最优策略:能走就走,不能走就等。不存在"提前等待"能获得更优解的情况,因为每一步都是往右走一格,越早到达当前格子,后续的灵活性越大。
样例演示
第一组 :
| 步骤 | 目标格子 | ||
|---|---|---|---|
| 初始 | 1 | - | 0 |
| 1 | 2 | 2 | |
| 2 | 3 | 4 | |
| 3 | 4 | 5 | |
| 4 | 5 | 6 |
答案为 6。
复杂度分析
- 时间复杂度:
,单次遍历。
- 空间复杂度:
,存储数组(也可边读边算做到
)。
代码
#include <bits/stdc++.h>
using namespace std;
int main(){
int t;
scanf("%d",&t);
while(t--){
int n;
scanf("%d",&n);
vector<long long> a(n);
for(int i=0;i<n;i++) scanf("%lld",&a[i]);
long long cur=0;
for(int i=1;i<n;i++){
cur = max(cur+1, a[i]);
}
printf("%lld\n",cur);
}
return 0;
}
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int t = Integer.parseInt(br.readLine().trim());
StringBuilder sb = new StringBuilder();
while(t-- > 0){
int n = Integer.parseInt(br.readLine().trim());
StringTokenizer st = new StringTokenizer(br.readLine().trim());
long[] a = new long[n];
for(int i=0;i<n;i++) a[i] = Long.parseLong(st.nextToken());
long cur = 0;
for(int i=1;i<n;i++){
cur = Math.max(cur+1, a[i]);
}
sb.append(cur).append('\n');
}
System.out.print(sb);
}
}

京公网安备 11010502036488号