2024江苏省赛 H. 完蛋,我被房产包围了 【费用流、分时图】

完蛋,我被房产包围了

1

n ≤ 200 , ∑ n ≤ 1 0 4 n \leq 200, \sum n \leq 10^4 n200,n104

求出最大利润

思路

每个代理商每次买房狂潮只能卖出 1 1 1 套房子,小红卖出一套房子贬值 1 1 1 元,小绿卖出一套房子贬值 ⌈ a i 10 ⌉ \lceil \dfrac{a_i}{10} \rceil 10ai,小蓝卖出一套房子不贬值。
因此我们应该尽可能让小蓝卖房子,其次再交给小红,最后没得选择才交给小绿,因为卖出房子总归是有利润的,只是多少的问题,所以最优的策略一定是尽可能卖更多数量的房子。

我们先将小红和小蓝占满,让他们每次狂潮都有房子卖,他们卖不完的房子再交给贬值最多的小绿,由于小绿优先选择价值最高的房子贩卖,所以我们把不需要卖的房子交给小绿,并不会影响我们最终的最大利润决策

通过上述的分析,我们不难发现:对于每一次 买房狂潮 ,我们应该尽可能跑满最大流,并且要最小化贬值,也就是最小费用最大流

我们可以这样建模:

  1. 对于每个代理商 j j j,建立其在时刻 i i i 的点: i d ( i , j ) id(i, j) id(i,j),这里总共有 3 n 3n 3n 个分时点
  2. 对于每个代理商 j j j 的每个时刻点,我们连边 i d ( i − 1 , j ) → i d ( i , j ) id(i - 1, j) \rarr id(i, j) id(i1,j)id(i,j),容量为 ∞ \infty ,费用为 0 0 0,表示这个代理商手里持有的房子,随着时间推移而保留
  3. 对于每次买房狂潮,我们对当前时刻 i i i 的每个代理商 j j j 连边: i d ( i , j ) → T id(i, j) \rarr T id(i,j)T,容量为 1 1 1,费用为 0 0 0,表示每个代理商在这个时刻最多贩卖一套房子
  4. 对于每个房子 x x x,连边: S → x S \rarr x Sx,容量为 1 1 1,费用为 0 0 0,表示这个房子最多被卖 1 1 1 次(这里新增 O ( n ) O(n) O(n) 个点),连边: x → T x \rarr T xT,容量为 1 1 1,费用为 a x a_x ax,表示这个房子不交给代理商,最后没有被卖出去的贬值,也即是一块钱利润都没有
  5. 对于每个房子 x x x,我们在其分配的时刻 i i i,对每个代理商连边:
    x → i d ( i , 0 ) x \rarr id(i, 0) xid(i,0),容量为 1 1 1,费用为 1 1 1,表示通过小红卖这套房要贬值 1 1 1
    x → i d ( i , 1 ) x \rarr id(i, 1) xid(i,1) ,容量为 1 1 1,费用为 ⌈ a i 10 ⌉ \lceil \frac{a_i}{10} \rceil 10ai,表示通过小绿卖这套房要贬值 ⌈ a i 10 ⌉ \lceil \frac{a_i}{10} \rceil 10ai
    x → i d ( i , 2 ) x \rarr id(i, 2) xid(i,2) ,容量为 1 1 1,费用为 0 0 0,表示通过小蓝卖不贬值

最后我们用 ∑ a i − ( S → T \sum a_i - (S \rarr T ai(ST最小费用最大流) 就是答案了

#include<bits/stdc++.h>
#define fore(i,l,r)	for(int i=(int)(l);i<(int)(r);++i)
#define fi first
#define se second
#define endl '\n'
#define ull unsigned long long
#define ALL(v) v.begin(), v.end()
#define Debug(x, ed) std::cerr << #x << " = " << x << ed;

const int INF=0x3f3f3f3f;
const long long INFLL=1e18;

typedef long long ll;

struct MCF {
    struct Edge {
        int v, c, w; //边终点、容量、费用
        Edge(int v, int c, int w) : v(v), c(c), w(w) {}
    };
    const int n;
    std::vector<Edge> e;
    std::vector<std::vector<int>> g;
    std::vector<ll> h, dis;
    std::vector<int> pre;
    bool dijkstra(int s, int t) {
        dis.assign(n + 1, std::numeric_limits<ll>::max());
        pre.assign(n + 1, -1);
        std::priority_queue<std::pair<ll, int>, std::vector<std::pair<ll, int>>, std::greater<std::pair<ll, int>>> que;
        dis[s] = 0;
        que.emplace(0, s);
        while (!que.empty()) {
            ll d = que.top().first;
            int u = que.top().second;
            que.pop();
            if (dis[u] < d) continue;
            for (int i : g[u]) {
                int v = e[i].v;
                int c = e[i].c;
                int w = e[i].w;
                if (c > 0 && dis[v] > d + h[u] - h[v] + w) {
                    dis[v] = d + h[u] - h[v] + w;
                    pre[v] = i;
                    que.emplace(dis[v], v);
                }
            }
        }
        return dis[t] != std::numeric_limits<ll>::max();
    }
    MCF(int n) : n(n), g(n + 1) {}
    void addEdge(int u, int v, int c, int w) {
        g[u].push_back(e.size());
        e.emplace_back(v, c, w);
        g[v].push_back(e.size());
        e.emplace_back(u, 0, -w);
    }
    std::pair<int, ll> flow(int s, int t) {
        int flow = 0;
        ll cost = 0;
        h.assign(n + 1, 0);
        while (dijkstra(s, t)) {
            for (int i = 1; i <= n; ++i) h[i] += dis[i];
            int aug = std::numeric_limits<int>::max();
            for (int i = t; i != s; i = e[pre[i] ^ 1].v) aug = std::min(aug, e[pre[i]].c);
            for (int i = t; i != s; i = e[pre[i] ^ 1].v) {
                e[pre[i]].c -= aug;
                e[pre[i] ^ 1].c += aug;
            }
            flow += aug;
            cost += ll(aug) * h[t];
        }
        return std::make_pair(flow, cost);
    }
};

int main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);
    int t;
    std::cin >> t;
    while(t--){
        int n;
        std::cin >> n;
        MCF mcf(4 * n + 10);
        int tot = 3 * n + 1;
        int S = ++tot, T = ++tot;

        auto get_id = [&](int time, int j) -> int {
            return n * j + time;
        };

        int ans = 0;
        fore(i, 0, n){
            if(i > 0){
                fore(j, 0, 3){
                    int lst = get_id(i - 1, j), now = get_id(i, j);
                    mcf.addEdge(lst, now, INF, 0);
                }
            }

            int opt;
            std::cin >> opt;
            if(opt == 1){
                int w;
                std::cin >> w;
                ans += w;
                int id = ++tot;
                mcf.addEdge(S, id, 1, 0);
                mcf.addEdge(id, get_id(i, 0), 1, 1);
                mcf.addEdge(id, get_id(i, 1), 1, (w + 9) / 10);
                mcf.addEdge(id, get_id(i, 2), 1, 0);
                mcf.addEdge(id, T, 1, w);
            }
            else{
                fore(j, 0, 3){
                    int now = get_id(i, j);
                    mcf.addEdge(now, T, 1, 0);
                }
            }
        }

        ans -= mcf.flow(S, T).se;

        std::cout << ans << endl;
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/628168.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vue3专栏项目 -- 五、权限管理(下)

1、创建Message组件 前面我们获取到了请求错误的信息&#xff0c;所以我们接下来做一个弹出框组件&#xff0c;让错误提示展示出来 我们把这个组件做成一个全局组件&#xff0c;它不仅可以显示错误的信息&#xff0c;还可以添加成功操作的信息&#xff0c;甚至还可以显示一个…

C# OpenCvSharp Demo - 最大内接圆

C# OpenCvSharp Demo - 最大内接圆 目录 效果 项目 代码 下载 效果 项目 代码 using OpenCvSharp; using System; using System.Diagnostics; using System.Drawing; using System.Drawing.Imaging; using System.Linq; using System.Windows.Forms; namespace OpenCvSh…

算法day07

第一题 30. 串联所有单词的子串 上题题意如下&#xff1a; 将w数组里面的字符串随机排列&#xff0c;只要在s字符串中找到相对应的w组成的字符串&#xff0c;则返回s中对应字符串首位元素的第一个下标&#xff1b; 有上述题意所知&#xff0c;解题思路如上一题故事&#xff0c…

React搭建-Next 学习-1

创建一个 Next.js 应用,node版本要高&#xff0c;16.5以上 npm淘宝镜像切为https://registry.npmmirror.com npm config set registry https://registry.npmmirror.com npx create-next-applatest//安装后 使用npm run dev 启动 Next.js 是围绕着 页面&#xff08;pages&am…

如何启用WooCommerce商城快捷结帐:3 种简单方法

使用WooCommerce商城快捷结帐可帮助您提高商店的转化率。 70%的顾客同意在线商店的快速结账流程会鼓励他们完成购买。 在结账过程中您让购物者完成的步骤越多&#xff0c;他们完成该流程的可能性就越小。 解决方案是什么&#xff1f; 通过跳过默认的WooCommerce商城购物车页…

怎么看电脑是固态还是机械硬盘?数据丢失怎么办

在数字化时代&#xff0c;电脑硬盘作为数据存储的核心部件&#xff0c;其类型直接关系到数据读写速度和存储效率。固态硬盘&#xff08;SSD&#xff09;与机械硬盘&#xff08;HDD&#xff09;作为目前市场上主流的两种硬盘类型&#xff0c;各有其优缺点。然而&#xff0c;对于…

【LeetCode刷题】27. 移除元素

1. 题目链接2. 题目描述3. 解题方法4. 代码 1. 题目链接 27. 移除元素 2. 题目描述 3. 解题方法 暴力法直接解决&#xff0c;用双层for循环&#xff0c;外层for循环找val&#xff0c;内层for循环做删除操作。双指针法&#xff0c;fast和slow。fast找不是val的值&#xff0c;…

网站如何启用HTTPS访问

在互联网的世界里&#xff0c;数据安全已经成为了每个网站和用户都不得不面对的问题。近期&#xff0c;网络信息泄露事件频发&#xff0c;让越来越多的网站开始重视起用户数据的安全性&#xff0c;因此启用HTTPS访问成为了一个热门话题。作为一名网络安全专家&#xff0c;我希望…

【C语言习题】6.逆序输出

文章目录 1.描述输入描述&#xff1a;输出描述&#xff1a;示例图&#xff1a; 2.解题思路3.具体代码4.代码讲解 1.描述 输入10个整数&#xff0c;要求按输入时的逆序把这10个数打印出来。逆序输出&#xff0c;就是按照输入相反的顺序打印这10个数。 输入描述&#xff1a; 一…

实战| 手把手教你实现俯卧撑实时计数:OpenCV+MediaPipe

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

《五》Word文件编辑软件调试及测试

上一期&#xff0c;我们已经把大致的框架给完成了&#xff0c;那么今天&#xff0c;我们就把剩下的什么复制啊&#xff0c;改变字体啊什么的给做一下。 那我们就一步一步的来就可以了&#xff1a; 新建word&#xff1a; void MyWord::fileNew() {qDebug()<<"hhh&…

在不同的应用系统创建Python虚拟环境

在不同的应用系统创建Python虚拟环境 在Linux上创建Python虚拟环境 一、在Ubuntu上创建Python虚拟环境 可以通过使用virtualenv工具来完成。下面是创建Python虚拟环境的步骤&#xff1a; 首先确保已经安装了python3-venv包&#xff08;如果没有安装&#xff0c;则需要运行命…

产品经理如何进行项目管理?

产品经理如何进行项目管理&#xff1f; 项目管理和产品管理在本质上还是有一定差别的。产品更关注的是产品、功能、方向和反馈&#xff0c;而项目则更关注进度、质量和测试等。如果团队没有项目经理&#xff0c;那么产品经理就需要兼顾对开发人员、项目进度等进行管理。 此时…

声纹识别在无人机探测上的应用

无人机在民用和军事领域的应用越来越广泛。然而&#xff0c;随着无人机数量的增加&#xff0c;"黑飞"现象也日益严重&#xff0c;对公共安全和隐私构成了威胁。因此&#xff0c;开发有效的无人机探测与识别技术变得尤为重要。及时发现黑飞无人机的存在进而对其型号进…

软考-下午题-试题一

1、概念 2、答题技巧和规范 问题1、2&#xff1a;直接看 格式&#xff1a; 问题3&#xff1a; 格式&#xff1a; 3、例题 eg2&#xff1a;可以以后写完问题4之后&#xff0c;把问题3补充完整 问题4&#xff1a; 问题4 官方解释&#xff1a; 问题4&#xff08;3‘&#xff09; 2…

AI智能对话绘画二合一系统源码 在线生成绘画 带完整的源代码包以及搭建教程

系统概述 AI智能对话绘画二合一系统源码是一款集成了自然语言处理、深度学习、计算机视觉等多种技术的智能系统。该系统通过强大的自然语言处理能力&#xff0c;能够与用户进行流畅的AI对话&#xff0c;无论是创作构思、风格选择还是技巧咨询&#xff0c;系统都能给出精准的建…

7集成学习评分卡

集成学习评分卡 学习目标 知道LightGBM基本原理掌握使用lightGBM进行特征筛选的方法1 Gradient Boosting算法回顾 Gradient Boosting 基本原理 训练一个模型m1,产生错误e1针对e1训练一个模型m2,产生错误e2针对e2训练第三个模型m3,产生错误e3 …最终预测结果是:m1+m2+m3+…GB…

如何去除AI写作痕迹?笔灵去AI痕迹,提升论文质量

AI助手大集合&#xff0c;猛戳进来&#xff01; 在工作和生活中&#xff0c;我经常使用各种各样的人工智能工具&#xff0c;如AI写作软件、AI语音助手、AI绘图工具等。我发现&#xff0c;这些工具能够极大地提高工作效率并简化日常生活。作为一名AI工具的忠实爱好者&#xff0…

TortoiseGit的安装

TortoiseSvn和TortoiseGit都是针对代码进行版本管理的工具&#xff0c;又俗称小乌龟&#xff0c;简洁而可视化的操作界面&#xff0c;免去繁琐的命令行输入。只需要记住常用的几个操作步骤就能快速上手。 TortoiseGit安装 1、TortoiseGit作为git的版本管理工具 &#xff0c;但…

粘贴图片上传,显示剪切板中的图片

<van-cell-group inset><van-fieldpaste.native"(e) > handlePasting(e, index)"autosizeplaceholder"请将图片粘贴到此处"/> </van-cell-group> <div class"img-list"><divclass"img-item"v-for"…