首页 > 其他分享 >USACO 2021.12 Platinum Paired Up

USACO 2021.12 Platinum Paired Up

时间:2023-10-16 13:00:15浏览次数:32  
标签:Platinum typedef int max ll Up Paired maxn 失配

洛谷传送门

LOJ 传送门

如果 \(T = 1\),可以把重量全部取相反数转化成 \(T = 2\)。接下来只考虑 \(T = 2\) 的情况。

下文的 \(m\) 代表原题中的 \(K\)。

设第 \(i\) 个 G 牛的位置和重量分别为 \(a_{0, i}, b_{0, i}\),第 \(i\) 个 H 牛的位置和重量分别为 \(a_{1, i}, b_{1, i}\)。

考虑 dp。dp 状态的前两维一定是 \(i, j\) 表示当前考虑了前 \(i\) 个 G 牛和前 \(j\) 个 H 牛的匹配。为了使匹配极大,还需要多记一维上一个失配的牛,无法承受。

考虑改变 dp 状态的含义,设 \(f_{i, j, 0/1}\) 表示当前考虑了前 \(i\) 个 G 牛和前 \(j\) 个 H 牛的匹配,上一个失配的牛是第 \(i\) 个 G 牛或者第 \(j\) 个 H 牛。

考虑转移。以 \(f_{i, j, 0}\) 为例。枚举连续的匹配数 \(k\),如果 \((i + 1, j + 1), (i + 2, j + 2), \ldots, (i + k, j + k)\) 都能形成匹配,那么 \(f_{i + k + 1, j + k, 0} \gets f_{i, j, 0} + b_{0, i + k + 1}\)。在此基础上,如果 \(a_{1, j + k + 1} > a_{0, i} + m\),那么可以切换失配的牛的品种,即 \(f_{i + k, j + k + 1, 1} \gets f_{i, j, 0} + b_{1, j + k + 1}\)。\(f_{i, j, 1}\) 类似。然后我们可以 \(O(n)\) 地转移:

code
ll f[maxn][maxn][2];
	
void solve() {
	mems(f, -0x3f);
	f[0][0][0] = f[0][0][1] = 0;
	for (int i = 0; i <= A; ++i) {
		for (int j = 0; j <= B; ++j) {
			for (int k = 0; i + k + 1 <= A && j + k <= B; ++k) {
				if (k && abs(a[0][i + k] - a[1][j + k]) > m) {
					break;
				}
				f[i + k + 1][j + k][0] = max(f[i + k + 1][j + k][0], f[i][j][0] + b[0][i + k + 1]);
				if (a[0][i + k + 1] - a[1][j] > m && j) {
					f[i + k + 1][j + k][0] = max(f[i + k + 1][j + k][0], f[i][j][1] + b[0][i + k + 1]);
				}
			}
			for (int k = 0; i + k <= A && j + k + 1 <= B; ++k) {
				if (k && abs(a[0][i + k] - a[1][j + k]) > m) {
					break;
				}
				f[i + k][j + k + 1][1] = max(f[i + k][j + k + 1][1], f[i][j][1] + b[1][j + k + 1]);
				if (a[1][j + k + 1] - a[0][i] > m && i) {
					f[i + k][j + k + 1][1] = max(f[i + k][j + k + 1][1], f[i][j][0] + b[1][j + k + 1]);
				}
			}
		}
	}
	printf("%lld\n", max(f[A][B][0], f[A][B][1]));
}

发现转移是把一条对角线取 \(\max\)。考虑类似差分,最后再前缀 \(\max\) 起来。以 \(f_{i, j, 0}\) 为例,可以选择让第 \(i + 1\) 个 G 牛失配,即 \(f_{i + 1, j, 0} \gets f_{i, j, 0} + b_{0, i + 1}\);可以选择让第 \(i + 1\) 个 G 牛和第 \(j + 1\) 个 H 牛匹配,即 \(f_{i + 1, j + 1, 0} \gets f_{i, j, 0}\);还要切换失配的牛的种类。找到最小的非负整数 \(k\) 使得 \(a_{1, j + k + 1} > a_{0, i} + m\),若 \((i + 1, j + 1), (i + 2, j + 2), \ldots, (i + k, j + k)\) 都能匹配,那么 \(f_{i + k, j + k, 1} \gets f_{i, j, 0}\)。

容易合理地预处理做到时空复杂度均为 \(O(n^2)\)。

code
// Problem: P7985 [USACO21DEC] Paired Up P
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P7985
// Memory Limit: 512 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

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

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

const int maxn = 5050;

ll K, n, m, A, B, f[maxn][maxn][2], a[2][maxn], b[2][maxn];
int g[maxn][maxn], nxt[2][maxn];

inline void upd(ll &x, ll y) {
	(y > x) && (x = y);
}

void solve() {
	scanf("%lld%lld%lld", &K, &n, &m);
	for (int i = 1, x, y; i <= n; ++i) {
		char op[9];
		scanf("%s%d%d", op, &x, &y);
		if (op[0] == 'G') {
			a[0][++A] = x;
			b[0][A] = y;
		} else {
			a[1][++B] = x;
			b[1][B] = y;
		}
	}
	if (K == 1) {
		for (int i = 1; i <= A; ++i) {
			b[0][i] = -b[0][i];
		}
		for (int i = 1; i <= B; ++i) {
			b[1][i] = -b[1][i];
		}
	}
	for (int i = A; i; --i) {
		for (int j = B; j; --j) {
			if (abs(a[0][i] - a[1][j]) <= m) {
				g[i][j] = g[i + 1][j + 1] + 1;
			}
		}
	}
	for (int i = 1; i <= A; ++i) {
		for (int j = 1; j <= B; ++j) {
			if (a[1][j] > a[0][i] + m) {
				nxt[0][i] = j;
				break;
			}
		}
	}
	for (int j = 1; j <= B; ++j) {
		for (int i = 1; i <= A; ++i) {
			if (a[0][i] > a[1][j] + m) {
				nxt[1][j] = i;
				break;
			}
		}
	}
	mems(f, -0x3f);
	f[0][0][0] = f[0][0][1] = 0;
	for (int i = 0; i <= A; ++i) {
		for (int j = 0; j <= B; ++j) {
			int k = max(nxt[1][j] - i - 1, 0);
			if (nxt[1][j] && k <= g[i + 1][j + 1] && j) {
				upd(f[i + k][j + k][0], f[i][j][1]);
			}
			k = max(nxt[0][i] - j - 1, 0);
			if (nxt[0][i] && k <= g[i + 1][j + 1] && i) {
				upd(f[i + k][j + k][1], f[i][j][0]);
			}
			upd(f[i + 1][j][0], f[i][j][0] + b[0][i + 1]);
			upd(f[i][j + 1][1], f[i][j][1] + b[1][j + 1]);
			if (abs(a[0][i + 1] - a[1][j + 1]) <= m) {
				upd(f[i + 1][j + 1][0], f[i][j][0]);
				upd(f[i + 1][j + 1][1], f[i][j][1]);
			}
		}
	}
	printf("%lld\n", K == 1 ? -max(f[A][B][0], f[A][B][1]) : max(f[A][B][0], f[A][B][1]));
}

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

标签:Platinum,typedef,int,max,ll,Up,Paired,maxn,失配
From: https://www.cnblogs.com/zltzlt-blog/p/17767126.html

相关文章

  • 戴森美发科技,呵护头皮水分0流失 戴森Supersonic™吹风机的头皮功效试验结果经中轻日用
    作为头发护理行业的领军品牌,戴森多年来一直持续研究头发科学,不断探知消费者对头发损伤的困扰与认知,致力于以创新科技为消费者提供健康科学的护发造型体验。自2016年戴森Supersonic™吹风机面世以来,戴森即以创新科技颠覆了传统的护发造型方式,也使健康护发的造型理念逐渐深入人心。日......
  • Secure Code Warrior Introduction to OWASP Top 10 Awareness (with latest updates
    MissingFunctionAccessControlAccesstothesefunctionalitiesshouldberestrictedtoauthenticatedusers.However,thecurrentmechanismonlycheckswhetherauserexists.Anyuser,authenticatedornot,willbeabletoaccessrestrictedinformation.U......
  • update left join 在MySQL和SQL Server使用方式区别
    (1)MySQL使用UPDATEhayl_service_infot1leftjoinhayl_Old_infot2ont1.CERT_NO=t2.CERT_NOsett1.AAP0112=t2.ADDRESSwheret1.AAP0112=''(2)SQLServers使用UPDATEhayl_service_infosetAAP0112=t2.ADDRESSfromhayl_service_infot1leftjoin......
  • vue3中setup
    和vue2不同的是vue3中的script中带有setup标签里面的setup相当于vue2中的data和methds空间可以放置函数,也可以执行函数在写时需要有return返回值<scriptsetup></script>setup执行发生在页面之前所以不能使用this函数,一般通过ref绑定组件上的值进行修改 使用函数例子......
  • Lattice-Based Signatures with Tight Adaptive Corruptions and More
    Abstract.Weconstructthefirsttightlysecuresignatureschemesinthemulti-usersettingwithadaptivecorruptionsfromlattices.Instarkcontrasttotheprevioustightconstructionswhosesecurityissolelybasedonnumber-theoreticassumptions,our......
  • Mysql分表后同结构不同名称表之间复制数据以及Update语句只更新日期加减不更改时间
    场景SpringBoot+Mybatis+定时任务实现大数据量数据分表记录和查询:SpringBoot+Mybatis+定时任务实现大数据量数据分表记录和查询_mybatis定时任务创建日表_霸道流氓气质的博客通过以上分表实现的同结构不同表名之间的表,如何将一个表中的数据复制到另一个表中,且将日期字段进行同样的......
  • 深度学习不如GBLUP的原因
    深度学习,尤其是最近几年,被广泛宣传为可以处理复杂问题的强大工具。然而,我们必须理解,在某些特定的问题或数据集上,传统的方法有时可能更适合或更稳定。以下是一些可能解释为什么在考虑G×E交互效应时,深度学习没有表现得像GBLUP模型那么好的原因:数据量和复杂性:深度学习模型,特别是......
  • C语言 strdup函数把字符串复制到新空间
    头文件是string.h。根据传入的字符串参数,malloc分配空间并复制,返回首地址,该地址通过free来释放。#include<stdio.h>#include<malloc.h>#include<string.h>intmain(){chara[20]="123";char*b=strdup(a);printf("%s\n",b);free(b);......
  • [机器学习] 3. 镜像下降 Mirror Descent 与线性耦合 Linear Coupling
    MLTheory太魔怔了!!!!!我们来考虑更快的下降算法。对\(L\)-smooth的GradientDescent,我们有两种视角来看它。一种是局部视角,梯度方向相近的点的函数值一定会下降,另一种是全局视角,用一个二次函数为整个\(f\)提供了一个lowerbound。当局部梯度的范数很大时,函数值会下降的很快;当......
  • 金蝶EAS myUploadFile任意文件上传漏洞
    漏洞简介金蝶EAS及EASCloud是金蝶软件公司推出的一套企业级应用软件套件,旨在帮助企业实现全面的管理和业务流程优化。金蝶EAS及EAScloud存在任意文件上传漏洞影响版本金蝶EAS8.0,8.1,8.2,8.5金蝶EASCloud8.6私有云,8.6公有云,8.6.1,8.8漏洞复现fofa语法:app="Kingdee-EA......