[CF1203F2] Complete the Projects - 邻项交换排序,dp
Description
给定n个任务和一个初始评级r,对于每个任务都有一个评级要求,当且仅当达到评级要求及以上时才能去做任务,做完一个任务评级都会发生相应改变,求最多能完成多少任务
Solution
首先根据人类智慧,(b_i ge 0) 的先做掉,并且这部分一定按照 (a_i) 升序,如果 (a) 相同那么要按照 (b) 降序
(b_i < 0) 的部分,按照邻项交换排序推导一下,发现按照 (a+b) 降序即可
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 105;
const int M = 60005;
int f[2][M];
int n, r;
struct Node
{
int a, b;
bool operator<(const Node &rhs) const
{
if ((b >= 0) != (rhs.b >= 0))
return b >= 0;
if (b >= 0)
if (a != rhs.a)
return a < rhs.a;
else
return b > rhs.b;
return a + b > rhs.b + rhs.a;
}
} node[N];
signed main()
{
ios::sync_with_stdio(false);
cin >> n >> r;
for (int i = 1; i <= n; i++)
cin >> node[i].a >> node[i].b;
sort(node + 1, node + n + 1);
memset(f, -0x3f, sizeof f);
int ans = 0;
f[0][r] = 0;
for (int i = 1; i <= n; i++)
{
int p = i & 1, q = p ^ 1;
for (int j = 0; j < M; j++)
f[p][j] = f[q][j];
for (int j = 0; j < M; j++)
{
if (j - node[i].b < 0 || j - node[i].b >= M)
continue;
if (j - node[i].b < node[i].a)
continue;
f[p][j] = max(f[p][j], f[q][j - node[i].b] + 1);
}
for (int j = 0; j < M; j++)
ans = max(ans, f[p][j]);
}
cout << ans << endl;
}