试题编号: 202212-2
试题名称: 训练计划
时间限制: 1.0s
内存限制: 512.0MB
为了计算每个科目的最晚开始时间,我们需要确保每个科目在最晚开始时间开始训练时,依赖的科目已经完成训练,并且所有训练在规定的天数内完成。
以下是详细的步骤和代码:
详细步骤
-
初始化:
- 读取输入的天数 [
n
] - 读取每个科目依赖的科目编号 [
pre
] - 读取每个科目所需的训练天数 [
cost
]
- 读取输入的天数 [
-
计算最早开始时间:
-
对于每个科目,如果有依赖的科目[
i
],则最早开始时间为依赖科目结束时间加其消耗时间:
[earliest[pre[i]]+cost[pre[i]]
]
-
如果最早开始时间加上训练天数超过了 [
n
]天,则设置 [flag
] 为 [false
],标记未完成训练,只输出最早时间,不输出最迟时间。
-
-
计算最晚开始时间:
- 初始化每个科目的最晚开始时间为 [
n - cost[i] + 1
] - 从后向前遍历科目,如果有依赖的科目[
pre[i]
] ,则更新依赖科目的最晚开始时间[latest[pre[i]]
] 为:
[min(latest[i]-cost[pre[i]],latest[pre[i]])
]
- 初始化每个科目的最晚开始时间为 [
-
输出结果:
- 输出每个科目的最早开始时间,记得空开每个数。
- 如果 [
flag
] 为 [false
],则输出 [0
]并结束程序。 - 否则,输出每个科目的最晚开始时间。
代码解释
#include<bits/stdc++.h>
#define N 1000
#define ll long long
using namespace std;
int main() {
int n, m, pre[N], cost[N] = {0};
ll earliest[N] = {0}, latest[N] = {0};
bool flag = true;
// 读取距离大赛开幕的天数 n 和训练科目的数量 m
cin >> n >> m;
// 读取每个科目依赖的科目编号
for (int i = 1; i <= m; ++i) cin >> pre[i];
// 读取每个科目所需的训练天数
for (int i = 1; i <= m; ++i) cin >> cost[i];
// 计算每个科目的最早开始时间和最晚开始时间
for (int i = 1; i <= m; ++i) {
earliest[i] = 1; // 初始化最早开始时间为 1
latest[i] = n - cost[i] + 1; // 初始化最晚开始时间为 n - cost[i] + 1
// 如果有依赖的科目,则最早开始时间为依赖科目结束时间加 1 天
if (pre[i] != 0) earliest[i] = earliest[pre[i]] + cost[pre[i]];
// 如果最早开始时间加上训练天数超过了 n 天,则设置 flag 为 false
if (earliest[i] + cost[i] - 1 > n) flag = false;
// 输出每个科目的最早开始时间
cout << earliest[i] << " ";
}
cout << endl;
// 如果 flag 为 false,表示无法在规定天数内完成所有训练,程序结束
if (!flag) return 0;
else {
// 从后向前遍历每个科目,更新依赖科目的最晚开始时间
for (int i = m; i >= 1; --i)
if (pre[i] != 0)
latest[pre[i]] = min(latest[i] - cost[pre[i]], latest[pre[i]]);
// 输出每个科目的最晚开始时间
for (int i = 1; i <= m; ++i) cout << latest[i] << " ";
}
return 0; // 程序结束
}