首页 > 其他分享 >「解题报告」CF739E Gosha is hunting

「解题报告」CF739E Gosha is hunting

时间:2023-06-01 14:35:43浏览次数:42  
标签:insert hunting val CF739E top second Gosha op first

来南京第二天就感冒了,然后嗓子疼,头疼炸了。哈哈。

等等是不是春季赛前我也这个状态来着。呃呃。好像确实一模一样。


这玩意跟 DP 有个鬼关系。

下面两个概率用 \(u_i, v_i\) 表示。

首先如果只选两者之一,贡献为 \(u_i / v_i\),如果两者都选那么贡献为 \(u_i + v_i - u_iv_i\)。

我们要最大化和,这东西看起来就很费用流。先建个模先。

考虑二分图模型,源点向两个点连流量 \(a, b\),费用 \(0\) 的边,分别表示选 \(u_i\) 和 \(v_i\)。然后这两个点向每个点 \(i\) 连费用 \(u_i / v_i\),流量 \(1\) 的边。考虑 \(-u_i v_i\) 的贡献,我们可以先从 \(i\) 向汇点连 \(0\) 费用的边,然后再连一条 \(-u_i v_i\) 费用的边,这样正好满足贡献。

然后发现一边只有两个点,这东西太模拟费用流了,直接大力模拟。大致分 \(S \to a \to i \to T\),\(S \to b \to i \to T\),\(S \to a \to i \to b \to j \to T\),\(S \to b \to i \to b \to j \to T\) 四种,具体懒得写了,太麻烦了。

反正最后复杂度是 \(O(n \log n)\) 的。

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2005;
priority_queue<pair<double, int>> q[6];
int n, a, b;
double u[MAXN], v[MAXN];
int type[MAXN];
void update() {
    for (int i = 0; i < 6; i++) while (q[i].size()) {
        if (type[q[i].top().second] != i % 3) {
            q[i].pop();
        } else break;
    }
}
void insert(int x, int t) {
    type[x] = t;
    if (type[x] == 0) {
        q[0].push({ u[x], x });
        q[3].push({ v[x], x });
    }
    if (type[x] == 1) {
        q[1].push({ v[x] - u[x] * v[x], x });
        q[4].push({ v[x] - u[x], x });
    }
    if (type[x] == 2) {
        q[2].push({ u[x] - u[x] * v[x], x });
        q[5].push({ u[x] - v[x], x });
    }
}
int main() {
    scanf("%d%d%d", &n, &a, &b);
    for (int i = 1; i <= n; i++) {
        scanf("%lf", &u[i]);
    }
    for (int i = 1; i <= n; i++) {
        scanf("%lf", &v[i]);
    }
    for (int i = 1; i <= n; i++) {
        insert(i, 0);
    }
    double ans = 0;
    while (a || b) {
        int op;
        double val = -1e18;
        if (a) {
            // u[i]
            if (q[0].size() && q[0].top().first > val)
                val = q[0].top().first, op = 1;
            // u[i] - v[i] + v[j]
            if (q[3].size() && q[5].size() && 
                q[3].top().first + q[5].top().first > val)
                val = q[3].top().first + q[5].top().first, op = 2;
            // u[i] - v[i] + v[j] - u[j]v[j]
            if (q[1].size() && q[5].size() &&
                q[1].top().first + q[5].top().first > val)
                val = q[1].top().first + q[5].top().first, op = 3;
            // u[i] - u[i]v[i]
            if (q[2].size() && q[2].top().first > val)
                val = q[2].top().first, op = 4;
        }
        if (b) {
            // v[i]
            if (q[3].size() && q[3].top().first > val)
                val = q[3].top().first, op = 5;
            // v[i] - u[i] + u[j]
            if (q[0].size() && q[4].size() && 
                q[0].top().first + q[4].top().first > val)
                val = q[0].top().first + q[4].top().first, op = 6;
            // v[i] - u[i] + u[j] - u[j]v[j]
            if (q[2].size() && q[4].size() &&
                q[2].top().first + q[4].top().first > val)
                val = q[2].top().first + q[4].top().first, op = 7;
            // v[i] - u[i]v[i]
            if (q[1].size() && q[1].top().first > val)
                val = q[1].top().first, op = 8;
        }
        if (op == 1) a--, insert(q[0].top().second, 1);
        if (op == 2) a--, insert(q[5].top().second, 1), insert(q[3].top().second, 2);
        if (op == 3) a--, insert(q[5].top().second, 1), insert(q[1].top().second, 3);
        if (op == 4) a--, insert(q[2].top().second, 3);
        if (op == 5) b--, insert(q[3].top().second, 2);
        if (op == 6) b--, insert(q[4].top().second, 2), insert(q[0].top().second, 1);
        if (op == 7) b--, insert(q[4].top().second, 2), insert(q[2].top().second, 3);
        if (op == 8) b--, insert(q[1].top().second, 3); 
        update();
        ans += val;
    }
    printf("%.12lf\n", ans);
    return 0;
}

标签:insert,hunting,val,CF739E,top,second,Gosha,op,first
From: https://www.cnblogs.com/apjifengc/p/17448879.html

相关文章

  • 4.[1201D - Treasure Hunting](https://codeforces.com/problemset/problem/1201/D)
    4.1201D-TreasureHunting题目意思:在一个n*m的地图上面,左下角的坐标是(1,1),最开始你位于左下角,一秒钟你可以进行往左或者往右的操作,你只能在一些特殊的列上面进行往上移动的操作,你不可以往下移动。现在告诉你k个宝藏的坐标信息以及哪些列是允许往上的,问最后至少要几秒可以遍历k......
  • k8s版MongoShake数据迁移工具
    说明我们原有的MongoDB副本集集群部署在k8s上,后因业务需求,在k8s集群外使用三台虚拟机组建了一套相同架构的MongoDB副本集集群,现想将在k8s集群上mongoDB数据迁移到......
  • contest739E. Gosha is hunting 题解报告
    题目地址题意:现在一共有\(n\)只神奇宝贝。你有\(a\)个『宝贝球』和\(b\)个『超级球』。『宝贝球』抓到第\(i\)只神奇宝贝的概率是\(p_i\),『超级球』抓到的......
  • 题解 [ABC227F] Treasure Hunting
    简单DP,当时赛时没做出来,怎么回事呢。在DP过程中并不好维护前\(k\)大都是什么,没有办法把它放到状态里,因此我们枚举第\(k\)大数的下标\(a_{x,y}\)。然后就好办了,设......
  • HDU 3468 Treasure Hunting
    DescriptionDoyouliketreasurehunting?Today,withoneofhisfriend,iSeaisonaventuretripagain.Asmostmoviesaid,theyfindsomanygoldhid......