EPIC Institute of Technology Round Summer 2024 (Div. 1 + Div. 2)

EPIC Institute of Technology Round Summer 2024 (Div. 1 + Div. 2)

D题题解

赛时这道题做出来了,但是手速慢了,这题可以o(nlogn)做结果一直在想怎么构造二维dp。

解法:

  • 首先,Alice拿最小的还是次小的来防止Bob拿走她能拿的部分呢?答案是永远拿最小的,因为她为了防止Bob拿走次小的部分的话只会损失掉当前最小的,而不阻止Bob拿掉次小的部分最坏情况是损失掉最小的。所以拿次小的不会更优,只要拿最小的即可。
  • 其次,对于Alice已经确定了,对于Bob而言呢?此时发现Alice方案确定,不会受Bob影响(即永远拿最小的),那对于Bob而言就是尽量拿多点,假设Bob拿了m种,那么答案就是n-m。
  • 离散化加cnt数组记录。跑一遍用堆优化的反悔贪心完美解决。

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define N 5'005
#define endl '\n'
const int mod = 998244353;
int n, a[N], dp[N][N];
map<int, int> vis;
bool check(int x)
{
    priority_queue<int> q;
    int js = 0;
    for (int i = 1; i <= n; i++)
    {
        if (js >= vis[a[i]])
        {
            q.push(vis[a[i]]);
            js -= vis[a[i]];
        }
        else if (!q.empty() && q.top() > vis[a[i]])
        {
            js += q.top() - vis[a[i]];
            q.pop();
            q.push(vis[a[i]]);
            js++;
        }
        else
            js++;
    }
    if (q.size() >= x)
        return 1;
    return 0;
}
void solve()
{
    cin >> n;
    vis.clear();
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        vis[a[i]]++;
    }
    sort(a + 1, a + 1 + n);
    n = unique(a + 1, a + 1 + n) - a - 1;
    int l = 1, r = n, ans = 0;
    while (l <= r)
    {
        int mid = (l + r) >> 1;
        if (check(mid))
        {
            l = mid + 1;
            ans = mid;
        }
        else
            r = mid - 1;
    }
    cout << n - ans << endl;
}
signed main()
{
    int t = 1;
    cin >> t;
    while (t--)
        solve();
    return 0;
}

题外话,赛时真应该看一下E的,一个树上二维dp,思维量很小

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值