题目链接:
解题思路:
定义状态:f[i] 从i ~~n的最大空闲时间
状态转移:
1: 无任务:f[i] = max(f[i], f[i + 1] + 1);
2: 有任务:f[i] = max(f[i], f[i + time[i]]); // f[i]与任务结束后的时间即f[i + time[i]]取最大值
递推顺序:按开始时间从大到小递推:
为什么要按开始时间从大到小递推??
因为每个任务的开始后都会存在一段持续的执行任务期间,此时是不可转移的如图:
在任务1执行期间任务此时时间枚举到任务2, 3开始的时间,但因为任务1仍在执行,所以任务2, 3的状态是不可以被更新的,所以为了防止前面任务的影响,我们可以按任务开始时间从到小开始枚举
代码如下:
#include <cstdio> #include <vector> #include <iostream> using namespace std; const int N = 10010; int f[N]; int n, k; vector<int> task[N]; int main() { cin >> n >> k; for (int i = 1; i <= k; i ++ ) { int s, t; scanf("%d %d", &s, &t); task[s].push_back(t); } for (int i = n; i >= 1; i -- ) if (task[i].size()) for (int j = 0; j < task[i].size(); j ++ ) f[i] = max(f[i], f[i + task[i][j]]); else f[i] = max(f[i], f[i + 1] + 1); cout << f[1] << endl; return 0; }