首页 > 其他分享 >AtCoder Regular Contest 125 E Snack

AtCoder Regular Contest 125 E Snack

时间:2023-04-26 13:58:39浏览次数:42  
标签:AtCoder typedef Snack 源点 long Regular maxn 零食

洛谷传送门

AtCoder 传送门

很棒的 flow 题,考虑建二分图。

源点向每种零食连边权为 \(a_i\) 的边,每种零食向每个孩子连边权为 \(b_j\) 的边,每个孩子向汇点连边权为 \(c_j\) 的边,这个图的最大流就是答案。

直接跑最大流肯定 T,考虑最大流等价于求这个图的最小割,因此转而求最小割。

发现如果钦定每个零食归源点还是归汇点,那么每个孩子要么断掉所有连向它的归源点的边,要么断掉它连汇点的边。

设归源点的零食个数为 \(x\),每个孩子的最小代价即 \(\min(c_j, b_j \times x)\)。

既然代价只跟 \(x\) 有关了,那我们就枚举 \(x\),零食肯定把最小的 \(n - x\) 个割掉;把所有孩子按照 \(\frac{c_j}{b_j}\) 排序,\(c_j \le b_j \times x\) 的孩子代价就为 \(c_j\),否则为 \(b_j \times x\)。

做完了!太妙了。

code
// Problem: E - Snack
// Contest: AtCoder - AtCoder Regular Contest 125
// URL: https://atcoder.jp/contests/arc125/tasks/arc125_e
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<ll, ll> pii;

const int maxn = 200100;

ll n, m, a[maxn], c[maxn], d[maxn], e[maxn];
struct node {
	ll a, b;
} b[maxn];

inline bool operator < (const node &a, const node &b) {
	return a.b * b.a < b.b * a.a;
}

void solve() {
	scanf("%lld%lld", &n, &m);
	for (int i = 1; i <= n; ++i) {
		scanf("%lld", &a[i]);
	}
	for (int i = 1; i <= m; ++i) {
		scanf("%lld", &b[i].a);
	}
	for (int i = 1; i <= m; ++i) {
		scanf("%lld", &b[i].b);
	}
	sort(a + 1, a + n + 1);
	sort(b + 1, b + m + 1);
	for (int i = 1; i <= n; ++i) {
		c[i] = c[i - 1] + a[i];
	}
	for (int i = 1; i <= m; ++i) {
		d[i] = d[i - 1] + b[i].a;
		e[i] = e[i - 1] + b[i].b;
	}
	ll ans = 1e18;
	for (int i = 0; i <= n; ++i) {
		int l = 1, r = m, p = 0;
		while (l <= r) {
			int mid = (l + r) >> 1;
			if (b[mid].b <= i * b[mid].a) {
				p = mid;
				l = mid + 1;
			} else {
				r = mid - 1;
			}
		}
		// printf("%d %d %lld\n", i, p, c[n - i] + e[p] + (d[m] - d[p]) * i);
		ans = min(ans, c[n - i] + e[p] + (d[m] - d[p]) * i);
	}
	printf("%lld\n", ans);
}

int main() {
	int T = 1;
	// scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

/*
很棒的 flow 题,考虑建二分图
源点向每种零食连边权为 a_i 的边,每种零食向每个孩子连边权为 b_j 的边,每个孩子向汇点连边权为 c_j 的边
这个图的最大流就是答案
直接跑最大流肯定 T,考虑最大流等价于求这个图的最小割
转而求最小割
发现如果钦定每个零食归 S 还是归 T,那么每个孩子要么断掉所有连向它的归 S 的边,要么断掉它连 T 的边
设归 S 的零食个数为 x,每个孩子的最小代价即 min(c_j, b_j * x)
既然代价只跟 x 有关了,那我们就枚举 x,零食肯定把最小的 n - x 个割掉;
把所有孩子按照 c_j/b_j 排序,c_j >= b_j * x 的孩子代价就为 b_j * x,否则为 c_j
做完了!太妙了
*/

标签:AtCoder,typedef,Snack,源点,long,Regular,maxn,零食
From: https://www.cnblogs.com/zltzlt-blog/p/17355667.html

相关文章

  • AtCoder Regular Contest 126 D Pure Straight
    洛谷传送门AtCoder传送门很不错的状压。考虑先把最后作为答案的数聚到一起,再算它们的逆序对个数。设\(f_S\)为当前选的数集合为\(S\)的答案。有转移:选\(a_i\),答案加上之前选的比它大的数;不选\(a_i\),此时需要把左边的数或者右边的数往中间挪一个,答案加上左右两端的最......
  • Converting a regular DB2 DMS tablespace to LARGE
    ConvertingaregularDB2DMStablespacetoLARGEhttps://www.ibm.com/support/pages/converting-regular-db2-dms-tablespace-large#:~:text=Convert%20the%20tablespace%20to%20LARGE%20by,running%3A%20alter%20tablespace%20tbspace_name%20CONVERT%20TO%20......
  • AtCoder Regular Contest 115 F Migration
    洛谷传送门AtCoder传送门这种最大值最小化的题一般可以先考虑二分。设二分了一个\(mid\)。记\(A=(a_1,a_2,...,a_k)\)为表示每个棋子的位置的状态,如果\(A,B\)可以互相到达,就在它们之间连一条无向边。则要判断的是\(S=(s_1,s_2,...,s_k)\)和\(T=(t_1,t_2,...,t_k......
  • Codeforces Round #306 (Div. 2) D. Regular Bridge 构造
    Anundirectedgraphiscalledk-regular,ifthedegreesofallitsverticesareequalk.Anedgeofaconnectedgraphiscalledabridge,ifafterremovingitthegraphisbeingsplitintotwoconnectedcomponents.Buildaconnectedundirectedk-regularg......
  • AtCoder Beginner Contest 158
    AtCoderBeginnerContest158https://atcoder.jp/contests/abc158基础不牢,地动山摇D-StringFormation一个小小的STL应用#include<bits/stdc++.h>#definelllonglongusingnamespacestd;strings;intq,t,f;charc;intmain(){cin>>s>>q......
  • AtCoder Problem Difficulty
    ABC299之前.......
  • AtCoder Regular Contest 111 F Do you like query problems?
    洛谷传送门AtCoder传送门挺有意思的计数。计数感觉很难做,不妨转成期望,期望又可以转成概率之和。考虑枚举\(w\in[0,m-1]\),把\(>w\)的数设为\(1\),\(\lew\)的数设为\(0\)。那么期望就是所有\(w\),\(a_i\)为\(1\)的概率之和。对于一个\(i\),只有以下的操作能改变\(......
  • AtCoder ABC 299 ABCDEFG
    A-TreasureChest题意给定由\(\texttt{.}\)、\(\texttt{|}\)、\(\texttt{*}\)三种字符组成的长度为\(n\)的字符串\(s\),保证\(\texttt{|}\)的个数为\(2\),\(\texttt{*}\)的个数为\(1\)。判断\(\texttt{*}\)是否在两个\(\texttt{|}\)之间。代码#include<cstrin......
  • Atcoder Beginner Contest 299 G
    对于要打印的\(B\),我们首先尝试确定\(B_1\)。让\(f(x)(1≤x≤M)\)是最大的\(i\),使\(A_i=x\)。对于\(r:=\underset{{{1≤x≤M}}}{\min}f(x)\),我们可以证明\(B_1\)是\(A_1,A_2,...,A_r\)中的一个(否则,\(B\)是\(A_{>r}:=(A_r+1,Ar+2,...,A_N)\)的一个子序列,但......
  • AtCoder Beginner Contest 283 Ex Popcount Sum
    洛谷传送门AtCoder传送门记录一下这个神奇的套路。首先有\(\operatorname{popcount}(n)=n-\sum\limits_{i=1}^{\infty}\left\lfloor\frac{n}{2^i}\right\rfloor\)。证一下:\[\operatorname{popcount}(n)=\sum\limits_{i=0}^{\infty}\left\lfloor\dfrac{n}{2^i}\right......