[luogu] P1280 尼克的任务
题目详情
题目分析:dp[i]
表示剩余i
分钟时的最大空闲时间,类似01背包
那样的资源划分问题,i
代表还剩余多少时间,而非是第几分钟。所以我们一开始是从dp[n]
开始。如果剩余i时刚好没有任何任务,那就从上一个状态的最大空闲时间转移并加一。如果此时刚好有任务,就转移这个任务的开始时刻时的最大空闲时间。
- 时间复杂度为 O ( n ∗ k ) O(n * k) O(n∗k)。
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
int n, k, dp[11111], p, t;
vector<int> v[11111];//这里有链式前向星的感觉,所以也可以转化成图论最短路问题,边权时任务持续时间。
int main(){
scanf("%d%d", &n, &k);
while (k--){
scanf("%d%d", &p, &t);
v[p].push_back(t);
}
for (int i = n; i > 0; i--){
if (v[i].size())
for (int j = 0; j < v[i].size(); j++)
dp[i] = max(dp[i], dp[i + v[i][j]]);//当前有任务就从剩余i + v[i][j]分钟时转移。
else
dp[i] = dp[i + 1] + 1;//当前无任务,就从前一分钟转移并加一。
}
printf("%d", dp[1]);
}