leo101
tags:
- 贪心
 date: 2019-4-4
jag2017autumnJ Farm Village
题面
翻译
数轴上有 n 个村庄,每个村庄可以生产两个单位的粮食。在每个村庄生产一单位粮食有一定的代价。运输粮食的代价就是运输的距离。求最小代价使得每个村庄都有 一个单位的粮食。
题解
虽然在叶老的课件里这题是贪心优化费用流,但是讲起来和写起来和费用流没有毛关系
首先先把问题抽象一下,每个村庄可以有两个出口,需要一个入口,自给自足就可以看作是自己出口给自己,然后
根据一般套路准备两个堆,一个出口一个进口。
————叶老
首先预处理一下,把 d 取前缀和,方便计算距离
那么我们先贪心的想(也就是不计之后的代价),把这一次的出口与之前的入口需求相匹配,如果可以优化答案(也就是他们之间的距离 + \(G_i\)比相匹配的节点自给自足更优),那么就直接使用
然后就有反悔操作,就是更加后面的节点的出口,匹配前面我们匹配上的这个节点,所以每当我们根据贪心取完一次后(贪心每次是从入口堆里取最小值与当前的出口相匹配),就再往入口堆里面丢一个\(-(当前给答案的贡献) - dist[i] + g[i]\),方便之后反悔(说实话只有这里有点像网络流)
然后还有一个反悔就是这一次的出口不给之前的,给之后的,那么就往出口堆里丢一个\(-(给答案造成的贡献) - dist[i] + g[i]\),以便之后反悔
做完上述的发现自己的入口需求还没有解决,那么就从出口堆里取出一个最优的,与自己匹配
然后再往入口堆里丢一个\(-(对答案造成的贡献) - dist[j]\)以便之后反悔(用后面的出口来满足自己的入口)
代码
/**************************
  * Author : Leo101
  * Problem : Farm Village
  * Tags : 贪心
**************************/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <functional>
#define _FILE(s) freopen(#s".in", "r", stdin); freopen(#s".out", "w", stdout)
#define gi get_int()
typedef long long LL;
#define int LL
const int MAXN = 200010;
int get_int()
{
	int x = 0, y = 1; char ch = getchar();
	while (!isdigit(ch) && ch != '-') ch = getchar();
	if (ch == '-') y = -1, ch = getchar();
	while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
	return x * y;
}
int heap1[MAXN], heap2[MAXN], dist[MAXN], cnt1, cnt2;
int topHeap(int* heap, int &cnt)
{
	return heap[0];
}
int deleteHeap(int* heap, int &cnt)
{
	std :: pop_heap(heap, heap + cnt, std :: greater<int>());
	return heap[--cnt];
}
void insertHeap(int* heap, int val, int &cnt)
{
	heap[cnt++] = val;
	std :: push_heap(heap, heap + cnt, std :: greater<int>());
}
signed main()
{
	_FILE(code);
	int n = gi, ans = 0;
	for (int i = 1; i < n; i++) dist[i] = gi + dist[i - 1];
	for (int i = 0; i < n; i++) {
		int cost = gi;
		for (int j = 0; j < 2; j++) {
			int tmp = topHeap(heap1, cnt1) + dist[i] + cost;
			if (cnt1 != 0 && tmp < 0) {
				deleteHeap(heap1, cnt1); ans += tmp;
				insertHeap(heap1, -dist[i] - cost, cnt1);
				insertHeap(heap2, -dist[i] + cost - tmp, cnt2);
			} else {
				insertHeap(heap2, -dist[i] + cost, cnt2);
			}
		}
		int tmp = deleteHeap(heap2, cnt2) + dist[i];
		ans += tmp;
		insertHeap(heap1, -tmp - dist[i], cnt1);
	}
	printf("%lld\n", ans);
	return 0;
}
leo101的更多相关文章
- Luogu P3757 [CQOI2017]老C的键盘
		题目描述 老C的键盘 题解 显然对于每个数 x 都有唯一对应的 \(x/2\) , 然而对于每个数 x 却可以成为 \(x*2\) 和 \(x*2+1\) 的对应数 根据这一特性想到了啥??? 感谢l ... 
随机推荐
- 什么是 Opcache,如何使用 Opcache
			Opcode 是啥? 我们先看一下 PHP 的执行过程: PHP 初始化执行环节,启动 Zend 引擎,加载注册的扩展模块. 初始化后读取 PHP 脚本文件,Zend 引擎对 PHP 文件进行词法分析 ... 
- GTA5整合版
			GTA5mod整合版游戏介绍 GTA5mod整合版游戏是一款完美破解的游戏,玩家能够在游戏中享受最爽快的角色动作扮演玩法,在这里你将是一名强大的黑帮分子,在这个都市中,你将体验最真实的黑帮社会玩法.G ... 
- Python-local variable 'raw_password' referenced before assignment
			where? 执行Python程序的时候,报这个错 why? 变量作用域问题,在分支中定义的变量,当满足条件的时候则可以正确得到变量,当不满足条件的时候则报这个错 way? 把变量从分支中抽离到分支上 ... 
- CUMTCTF'2020 未完成 wp
			Web babysqli burp抓包,发现有 的过滤,用/**/过滤空格. 报错注入 payload username=admin&password='/**/or/**/extractva ... 
- List移除另外一个list的时候报错,java.lang.UnsupportedOperationException
			问题 编写代码的时候,使用Mybatis-plus分页查询返回的list,移除自己new的ArrayList报错 根据异常信息,发现mybatis-plus分页查询返回的list底层并没有实现remo ... 
- 【总结】Oracle数据库 查看表空间和增加表空间
			一.Oracle查看 表空间 的名称及其大小 查看 表空间的名称及其大小的SQL语句: select t1.tablespace_name,round(sum(bytes/(1024*1024)),0 ... 
- linux 路径结构
			/bin /boot /data /dev /etc /home /lib /lib64 /lost+found /media /mnt /opt /proc /root /run /sbin /sr ... 
- shell-变量输入内置read命令详解
			1. shell变量的输入 shell变量除了可以直接赋值或脚本传参外,还可以使用read命令从标准输入得. [语法格式] read [参数] [变量名] [常用参数] -p:指定读取值时的提示符: ... 
- 关于keytool和jarsigner工具签名的使用小结
			在我们日常Android应用开发中,我们都要对我们开发的apk做签名处理,或者加固,增强我们apk的安全性,防止被逆向反编译,在apk签名这块,我们一般采用JDK自动工具来签名,下面就对相关工具做个简 ... 
- 制作iconfont放到自己的公共组件库
			我们公司的icon是UI提供svg,我们转成iconfont. 这里就不详细说明怎么制作svg,可以上网搜一下,https://www.iconfont.cn/help/detail?spm=a313 ... 
