思路是從後面往前推,先拿一個數組記錄一下任務開始的的點,然後從後面開始b[i]等於0的話,ans[i]等於ans[i+1]+1,就是如果這個點沒有開始任務的話這個點的空餘時間就等於後面那個點的空餘時間加1.當遇到b[i]不等於0的時候,這時表示需要開始任務,動態轉移方程爲ans[i] = max(ans[i],ans[i + arr[q].b);i表示當前點位置 ,arr[q].b表示這個開始任務的點需要進行多久任務,由於同一個點可能有多個任務,所以需要循環,b[i]爲多少就循環多少次,q用來遍歷每個不同的需要開始任務的點。
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef struct test{
int a;
int b;
}test;
bool cmp(test x,test y){
return x.a > y.a;
}
int main()
{
test arr[10001];
int b[10001] = {0};
int ans[10001] = {0};
int n,k;
cin >> n >> k;
for(int i = 1;i <= k;i++){
cin >> arr[i].a >> arr[i].b;
b[arr[i].a]++;
}
sort(arr + 1,arr + k + 1,cmp);
int q = 1;
for(int i = k;i > 0;i--){
if(b[i] == 0){
ans[i] = ans[i + 1] + 1;
}else{
for(int j = 0;j < b[i];j++){
if(ans[arr[q].b + i] > ans[i]){
ans[i] = ans[arr[q].b + i];
q++;
}
}
}
}
cout << ans[1];
return 0;
}