[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;
}

相关文章:

  • 2021-04-15
  • 2021-12-29
  • 2021-10-18
  • 2021-12-27
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-05-17
  • 2021-09-12
  • 2021-06-23
  • 2022-12-23
相关资源
相似解决方案