重启系统(等级考试4级 2021-03 T) 解题思路
【Horn Studio】编程专栏: 重启系统(等级考试4级 2021-03 T) 解题思路
题目
题目描述
小明帮助管理一个处理数据的计算系统,有N个待处理的任务,需要按照顺序来完成这些任务, 即每次所完成任务的编号都要大于前一个完成任务的编号,且单个任务不可以分解完成。计算系统运行着一个奇怪的保护程序, 它限制了系统当前所能处理的数据量不能超过上次完成任务所处理的数据量。重启系统可以使它立刻恢复到最高性能(一开始系统拥有最高性能, 最高性能大于任何待处理任务的数据量)。小明有一次重启系统的权限(也可以不使用),你能帮他算出最多能完成几个任务吗?
输入
第一行: N (2 <= N <= 1000) 待处理的任务数 第二行: N个整数,每个任务的数据量
输出
输出只包括一行,这一行只包含一个整数,表示最多能完成的任务数。
样例输入 复制
10
1 5 4 3 2 10 9 8 7 6
样例输出 复制
9
提示
来源
思路
这道题跟上一登山,一 毛 一 样!啊这就神奇了。不过还是与登山有稍微那么亿点不同,主要就是需要倒序一下,然后再进行一系列复杂的计算,时间复杂度有点大(n),不过最大也就1000,不慌。上一题的登山代码是这样的:
#include <bits/stdc++.h> using namespace std; int n, down[1110], up[1110], a[1110]; int main() { cin >> n; for (int i = 1; i <= n; i++) cin >> a[i]; for (int i = 1; i <= n; i++) { up[i] = 1; for (int j = 1; j < i; j++) if (a[j] < a[i]) up[i] = max(up[i], up[j] + 1); } for (int i = n; i >= 1; i--) { down[i] = 1; for (int j = n; j > i; j--) if (a[j] < a[i]) down[i] = max(down[i], down[j] + 1); } int res = 0; for(int i=1;i<=n;i++) res = max(res, up[i] + down[i] - 1); cout << res; return 0; }
我们将这个代码利用一下,大致思路是一样的,不过,这个程序需要将数组倒序之后在计算,我们可以用着一个代码解决:
reverse(taskmgr + 1, taskmgr + n + 1);
另外,在每一次序列结束后都要加上类似于斐波拉且数列(但它不是)的算法,大体就是这种样子:
for (int i = 2; i <= n; i++) { dpleft[i] = max(dpleft[i - 1], dpleft[i]); }
至此,我们摸清了他们之间的关系,接下来就很简单了。
代码
#include <bits/stdc++.h> using namespace std; int dpleft[10005], dpright[10005], taskmgr[10005]; int n; int main() { cin >> n; for (int i = 1; i <= n; i++) { cin >> taskmgr[i]; dpright[i] = dpleft[i] = 1; } reverse(taskmgr + 1, taskmgr + n + 1); for (int i = 1; i <= n; i++) { for (int j = 1; j < i; j++) { if (taskmgr[i] >= taskmgr[j]) { dpleft[i] = max(dpleft[i], dpleft[j] + 1); } } } for (int i = 2; i <= n; i++) { dpleft[i] = max(dpleft[i - 1], dpleft[i]); } for (int i = n - 1; i >= 1; i--) { for (int j = n; j > i; j--) { if (taskmgr[i] <= taskmgr[j]) { dpright[i] = max(dpright[i], dpright[j] + 1); } } } for (int i = n - 1; i >= 1; i--) { dpright[i] = max(dpright[i], dpright[i + 1]); } int ans = 0; for (int x = 1; x <= n; x++) { ans = max(ans, dpleft[x] + dpright[x + 1]); } cout << ans; return 0; }