Codeforces Round 935 (Div. 3) - D. Seraphim the Owl (动态规划)

大家排成 n 人的队列,从 i=1 号开始,向猫头鹰谢拉菲姆请教生命的意义。不幸的是,基里尔当时正忙着为这问题编写传说,所以他来得晚了一些,站在了 n 这个人之后,排在了队伍的最后。基里尔对这种情况完全不满意,于是他决定贿赂一些排在他前面的人。

对于队列中的第 i i i 个人,基里尔知道两个值: a i a_i ai b i b_i bi 。如果此刻基里尔站在位置 i i i 上,那么他可以选择任意一个位置 j j j ,比如 j < i j<i j<i 并与位置 j j j 的人交换位置。在这种情况下,基里尔需要支付他 a j a_j aj 个金币。而对于 k k k 中的每一个 j < k < i j<k<i j<k<i ,基里尔都要向位置 k k k 的人支付 b k b_k bk 个金币。基里尔可以任意多次执行这个操作。

基里尔很节俭,所以他想花尽可能少的硬币,但是他又不想等太久,所以基里尔认为他应该排在 m m m 的第一位。

请帮助基里尔确定,为了不等太久,他最少需要花费多少金币。

输入

每个测试由几组输入数据组成。第一行包含一个整数 t ( 1 ≤ t ≤ 1 0 4 ) t ( 1≤t≤10^4 ) t(1t104) - 测试用例的数量。然后是测试用例的描述。

每个测试用例的第一行包含两个整数 n n n m ( 1 ≤ m ≤ n ≤ 200000 ) m ( 1≤m≤n≤200000 ) m(1mn200000)–分别是除基里尔之外的队列人数和基里尔最终位置的最大允许值。

第二行包含 n n n 个整数 a 1 , a 2 , … , a n a_1,a_2,…,a_n a1,a2,,an ,用空格分隔 ( 1 ≤ a i ≤ 1 0 9 ) ( 1≤a_i≤10^9 ) (1ai109)

第三行包含 n n n 个整数 b 1 , b 2 , … , b n b_1,b_2,…,b_n b1,b2,,bn ,以空格分隔 ( 1 ≤ b i ≤ 1 0 9 ) ( 1≤b_i≤10^9 ) (1bi109)

保证所有测试用例中 n n n 的值之和不超过 2 ⋅ 1 0 5 2⋅10^5 2105

输出

对于每个测试用例,输出一个整数 ——Kirill 需要花费的最少金币数。

Example

input

4
4 2
7 3 6 9
4 3 8 5
6 2
6 9 7 1 8 3
5 8 8 1 4 1
7 7
7 2 9 2 6 5 9
9 1 10 7 1 4 9
2 1
2 3
1 1

output

14
22
9
3

首先读懂题,如果我们现在在队尾位置 ( n + 1 ) (n+1) n+1想要去 c c c 位置,那么我们要花费 ∑ i = n c − 1 b [ i ] + a [ c ] \sum\limits^{c - 1}_{i = n}b[i] + a[c] i=nc1b[i]+a[c] 的钱。

对于这题我觉得DP的方法更容易理解,参考了洛谷RailgunZzzz大佬的题解,%%%。

这里开不了二维dp数组,因为范围太大,所以考虑用一维的。

这里用f[i]来代表从队尾到 j j j 位置的所有走法的最小花费。

这里首先分析,如果我们要从 j j j 点走到 i i i 点,那么就要花费 f [ j ] + a [ i ] + ∑ k = n j − 1 − ∑ k = n i f[j] + a[i] + \sum\limits_{k = n}^{j - 1} - \sum\limits_{k = n}^{i} f[j]+a[i]+k=nj1k=ni ,注意这里是从后往前走,不要搞反了。

对于那些求和符号,我们可以把 b b b 数组维护成一个前缀和数组
但是如果我们枚举两个点就会导致超时,所以我们观察一下这个式子,尝试用数学方式优化他。

f [ i ] = m i n ( f [ j ] + b [ j − 1 ] − b [ i ] + a [ i ] ) f[i] = min(f[j] + b[j-1] - b[i] + a[i]) f[i]=min(f[j]+b[j1]b[i]+a[i])

在这个式子中关于j的项仅有 f [ j ] + b [ j − 1 ] f[j] + b[j-1] f[j]+b[j1],因为我们是由上一个 j j j 状态转移到了 i i i状态, − b [ i ] + a [ i ] - b[i] + a[i] b[i]+a[i] 并不影响对于最小值的选取,所以可以把关于 i i i 的项提出来。

那么我们就得到了式子: f [ i ] = m i n ( f [ j ] + b [ j − 1 ] ) − b [ i ] + a [ i ] f[i] = min(f[j] + b[j-1]) - b[i] + a[i] f[i]=min(f[j]+b[j1])b[i]+a[i]

这时 m i n ( f [ j ] + b [ j − 1 ] ) min(f[j] + b[j-1]) min(f[j]+b[j1])就可以使用一个变量来维护,这样就保持到了 O ( N ) O(N) O(N)的时间复杂度。
只需要在循环中维护一个变量不断更新就能取到 m i n ( f [ n ] + b [ n − 1 ] , f [ n − 1 ] + b [ n − 2 ] , f [ n − 2 ] + b [ n − 3 ] , . . . . . . ) min(f[n] + b[n-1] , f[n-1] + b[n-2] , f[n-2] + b[n-3],......) min(f[n]+b[n1],f[n1]+b[n2],f[n2]+b[n3],......)

注意要开long long,不然会爆int

代码:

#include<iostream>
#include<cmath>
#include<cstring>
#pragma warning (disable : 4996)
using namespace std;
const int N = 2e5 + 10;


int a[N];
long long b[N];
long long f[N];
int n, m;

int main() {
	int T; cin >> T;
	while (T--) {
		memset(f, 0, sizeof f);	//每次需要初始化,不然wa
		memset(b, 0, sizeof b);
		memset(a, 0, sizeof a);

		scanf("%d%d", &n, &m);

		for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
		for (int i = 1; i <= n; i++) {
			scanf("%d", &b[i]);
			b[i] += b[i - 1];	//转化为前缀和数组
		}

		long long mm = b[n];	//维护最小值最好也开个long long

		for (int j = n; j >= 1; j--) {	//状态转移过程
			f[j] = mm - b[j] + a[j];
			mm = min(mm, f[j] + b[j - 1]);
			//整个过程来看,mm取到了
			//min(f[n] + b[n-1] , f[n-1] + b[n-2] , f[n-2] + b[n-3],......)
		}

		long long res = 1e18;	//注意取答案一定要开Longlong初始化为1e18,不然会出错

		//注意这里为什么遍历1~m取最小值,因为题目要求最少换到m
		//所以我们换到m的前面也是没问题的,如果能用更小的花费为什么不换呢
		for (int i = 1; i <= m; i++)res = min(res, f[i]);
		cout << res << endl;
	}
	return 0;
}

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

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

相关文章

Mysql数据库——主从复制与读写分离

目录 前言 一、主从复制 1.主从复制的定义 2.Mysql主从复制支持的类型 3.主从复制的过程 4. 主从复制出现的问题 5.解决方法 二、读写分离 1.读写分离的定义 2.读写分离的作用 3.读写分离作用场景 3.1基于程序代码内部实现 3.2基于中间代理层实现 4.主从复制与读…

Redis命令介绍

一、redis启动&#xff1a; 本地启动&#xff1a;redis-cli 远程启动&#xff1a;redis-cli -h host -p port -a password Redis 连接命令 1 AUTH password 验证密码是否正确 2 ECHO message 打印字符串 3 PING 查看服务是否运行 4 QUIT 关闭当前连接 5 SELECT index 切换…

UI设计案例,B端后台界面设计教程

B端产品是为“组织”提供服务&#xff0c;以业务为中心&#xff0c;追求时效性&#xff0c;在视觉上&#xff0c;内容为王&#xff0c;视觉为功能让步&#xff0c;追求简洁、清晰、克制、理性的视觉风格。B 端产品业务比较复杂&#xff0c;页面内容也会较多&#xff0c;B端界面…

Python与人工智能:气象领域的数据处理与模型优化

Python是功能强大、免费、开源&#xff0c;实现面向对象的编程语言&#xff0c;在数据处理、科学计算、数学建模、数据挖掘和数据可视化方面具备优异的性能&#xff0c;这些优势使得Python在气象、海洋、地理、气候、水文和生态等地学领域的科研和工程项目中得到广泛应用。可以…

LLM资料:中文embedding库

Highlight&#xff08;重点提示&#xff09; 理解LLM&#xff0c;就要理解Transformer&#xff0c;但其实最基础的还是要从词的embedding讲起。 毕竟计算机能处理的只有数字&#xff0c;所以万事开头的第一步就是将要处理的任务转换为数字。 面向中文的开源embedding库在自然…

MQ集合了

消息队列&#xff0c;FIFO &#xff1a;异步 解耦 削峰 复杂度上升 幂等 重复消费 消息丢失 / 可用性降低 mq故障 / 一致性要求 mq对比&#xff1a; activeMQ&#xff1a;jms规范&#xff0c;支持事务 xa协议 rabbitMQ&#xff1a;erlang 性能&#x1f44c; 高并发 多语…

react-router v6的Link组件relative属性解释

Link组件有一个名为relative的属性,值为route或path,默认为route 当Link的to为两个点时,配置relativeroute|path会有不同的效果, 之前由于路径嵌套不够深,看不出区别,于是尝试加深路径,一眼就看出了区别 官方解释 | React Router6 中文文档 下方代码请看根路径/cd及其二级路…

C++优先队列——priority_queue,函数对象,labmda表达式,pair等

头文件&#xff1a;#include<queue> 内部使用堆来实现&#xff0c;在需要或得最大的几个值或最小的几个值而不关心整个数组的顺序时非常好用。 用法&#xff1a; priority_queue<int, vector<int>, greater<int>>q; 第一个参数为堆中存储的元素。 …

vue 借助vue-amap插件对高德地图的简单使用

需求&#xff1a;实现点击获取经纬度、定位、对特殊位置标点及自定义信息窗体功能。 高德地图的官网API&#xff1a;概述-地图 JS API 1.4 | 高德地图API vue-amap的中文文档&#xff1a;组件 | vue-amap 实现&#xff1a; 1、安装vue-amap插件 npm install vue-amap --save…

AI预测福彩3D第20弹【2024年3月28日预测--第4套算法重新开始计算第6次测试】

今天继续对第4套算法进行测试&#xff0c;测试的目的主要是为了记录统计两套方案的稳定性和命中率&#xff0c;昨天的第二套方案已命中。今天是第5次测试&#xff0c;同样测试两个方案。废话不多说&#xff0c;直接上结果。 2024年3月28日福彩3D的七码预测结果如下 …

武忠祥《660题》高效刷题包+资料分享

660题的难度书虽然比较难&#xff0c;对于基础的考察比较深入&#xff0c;所以&#xff0c;有没有一种可能&#xff0c;做题太慢&#xff0c;是因为基础不好导致的&#xff01; 所以再继续做下去&#xff0c;就没有什么意义了&#xff0c;因为这就像是用一把钝刀去砍树&#x…

mybatis搭建开发环境

1.创建maven工程 2.配置pom.xml <!--数据库驱动--> <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version> </dependency> <!--Mybatis--> <depend…

vscode使用sftp上传

1.用vscode打开项目 2.安装一下这个sftp 3.使用快捷键 ctrlshiftP 打开指令窗口&#xff0c;输入 sftp:config&#xff0c;选中回车&#xff0c;在当前目录中会自动生成 .vscode 文件夹及 sftp.json 4.修改sftp.json文件配置&#xff0c;改成以下&#xff08;默认的参数可能上传…

八种顺序读写函数的介绍(fput/getc;fput/gets;fscanf,fprintf;fwrite,fread)

一&#xff1a;读写的含义的解释&#xff1a; 读&#xff08;读出&#xff09;&#xff1a;即从文件里面读出数据----------->和scanf从键盘里面读出数据类似 写&#xff08;写入&#xff09;&#xff1a;即把数据写入文件里面----------->和printf把数据写入到屏幕上类…

【leetcode】双“指针”

标题&#xff1a;【leetcode】双指针 水墨不写bug 我认为 讲清楚为什么要用双指针 比讲怎么用双指针更重要&#xff01; &#xff08;一&#xff09;快乐数 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为&#xff1a; 对于一个正整数&#xff0c;每一次将该数…

Unity 窗口化设置

在Unity中要实现窗口化&#xff0c;具体设置如下&#xff1a; 在编辑器中&#xff0c;选择File -> Build Settings。在Player Settings中&#xff0c;找到Resolution and Presentation部分。取消勾选"Fullscreen Mode"&#xff0c;并选择"Windowed"。设…

Linux:Jenkins:参数化版本回滚(6)

上几章我讲到了自动集成和部署 Linux&#xff1a;Jenkins全自动持续集成持续部署&#xff08;4&#xff09;-CSDN博客https://blog.csdn.net/w14768855/article/details/136977106 当我们觉得这个页面不行的时候&#xff0c;需要进行版本回滚&#xff0c;回滚方法我这里准备了…

Linux 反引号、单引号以及双引号的区别

1.单引号—— 单引号中所有的字符包括特殊字符&#xff08;$,,和\&#xff09;都将解释成字符本身而成为普通字符。它不会解析任何变量&#xff0c;元字符&#xff0c;通配符&#xff0c;转义符&#xff0c;只被当作字符串处理。 2.双引号——" 双引号&#xff0c;除了$,…

LangSAM项目优化,将SAM修改为MoblieSAM,提速5~6倍

Language Segment-Anything 是一个开源项目&#xff0c;它结合了实例分割和文本提示的强大功能&#xff0c;为图像中的特定对象生成蒙版。它建立在最近发布的 Meta 模型、segment-anything 和 GroundingDINO 检测模型之上&#xff0c;是一款易于使用且有效的对象检测和图像分割…

定时任务 之 cron 表达式

Cron 表达式产生的背景&#xff1a;在Unix系统中&#xff0c;用户经常需要设置一些周期性被执行的任务&#xff0c;如定期备份文件、发送邮件等。为了满足这种需求&#xff0c;Unix系统提供了crontab命令&#xff0c;允许用户定义任务的时间表&#xff0c;并在指定的时间点自动…
最新文章