DP 数组要全部初始化为 1
/**
* 开始时间:2024-07-05 17:12:26
* 预计完成时间:2024-07-05 17:30
* 作者:zhizhi_c
* 题目:P8816 [CSP-J 2022] 上升点列
* 版本:0.0
* 思路:考虑中间两点中间无任何点才能计算其用的自由点数量,跑一遍拓扑排序背包
*/
#include <bits/stdc++.h>
#define rep(i, b, e) for (auto i(b); i <= (e); i++)
#define req(i, b, e) for (auto i(b); i >= (e); i--)
#define range(i, b, e) for (auto i(b); i != (e); i++)
using namespace std;
const int N = 500, K = 100;
int n, k, ans;
int x[N+5], y[N+5], deg[N+5];
int dp[N+5][K+5];
vector<int> edge[N+5];
queue<int> q;
bool check(int p0, int p1) {
rep(i, 1, n) {
if ((i != p0 and i != p1) and
((x[i] >= x[p0] and x[i] <= x[p1]) and (y[i] >= y[p0] and y[i] <= y[p1])))
return false;
}
return true;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
cin >> n >> k;
rep(i, 1, n) cin >> x[i] >> y[i];
rep(i, 1, n) fill(dp[i], dp[i] + n+1, 1); //重点!!!
range(i, 1, n) rep(j, i+1, n) {
int p0 = make_pair(x[i], y[i]) < make_pair(x[j], y[j]) ? i : j, p1 = i ^ j ^ p0;
if (y[p0] <= y[p1] and check(p0, p1)) {
deg[p1]++;
edge[p0].emplace_back(p1);
}
}
rep(i, 1, n) {
if (not deg[i]) q.emplace(i);
}
for (; not q.empty(); q.pop()) {
int u = q.front();
for (auto v: edge[u]) {
int dis = x[v] + y[v] - x[u] - y[u];
req(i, k, dis-1) dp[v][i] = max(dp[v][i], dp[u][i - dis + 1] + dis);
if (not (--deg[v])) q.emplace(v);
}
}
rep(i, 1, n) rep(j, 0, k) ans = max(ans, dp[i][j] + k - j);
cout << ans;
return 0;
}