题解 : dp[i][j] 表示前 i 个选 j 个的最小需要的时间,
转移就是 dp[i][j] = min (dp[i - 1][j - 1],max(dp[i - 1][j] + a[i].d,a[i].t + a[i].d - 1));
剩下的暴力每一个数,看它和它前面的时间差有多少就可以了。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
const int maxn = 4005;
const int INF = 1e9 + 7;
int n,k;
struct node {
int t,d;
}a[maxn];
int dp[maxn][maxn] = {0};
bool cmp (const node a,const node b) {
return a.t < b.t;
}
int main () {
ios_base :: sync_with_stdio(false);
cin >> n >> k;
for (int i = 1;i <= n; ++ i) {
cin >> a[i].t >> a[i].d;
}
a[0].t = 0;
a[n + 1].t = 86401;
if (n == k) {
cout << 86400 << endl;
return 0;
}
sort (a + 1,a + n + 1,cmp);
for (int i = 0;i < maxn; ++ i) {
for (int j = 0;j < maxn; ++ j) dp[i][j] = INF;
}
dp[0][0] = 0;
for (int i = 1;i <= n; ++ i) {
dp[i][0] = max (dp[i - 1][0],a[i].t - 1) + a[i].d;
for (int j = 1;j <= min(k,i); ++ j) {
dp[i][j] = min (dp[i - 1][j - 1],max(dp[i - 1][j] + a[i].d,a[i].t + a[i].d - 1));
}
}
int ans = a[1].t - 1;
for (int i = 1;i <= n; ++ i) {
int u = min (k,i);
// cout << dp[i][u] << endl;
ans = max (ans,a[i + 1].t - dp[i][u] - 1);
}
cout << ans << endl;
return 0;
}