Educational Codeforces Round 158 (Rated for Div. 2)(A~E)(贪心,树形DP)

A - Line Trip 

        题意:有一条路,可以用一条数线来表示。你位于数线上的点 0 ,你想从点 0 到点 x ,再回到点 0。你乘汽车旅行,每行驶 1个单位的距离要花费 1 升汽油。当您从点 0出发时,汽车已加满油(油箱中的油量已达到最大值)。在 a1,a2,…,an点有 n 个加油站。到达加油站后,为汽车加满油。注意只能在加油站加油, 0 和 x点没有加油站。你必须计算出你的汽车油箱的最小容积(以升为单位),这样你才能从点 0行驶到点 x 并返回到点 0 。

        思路:求一下相邻加油站的距离最大值即可,注意最后一个加油站要先到点x再回来。

        

// Problem: A. Line Trip
// Contest: Codeforces - Educational Codeforces Round 158 (Rated for Div. 2)
// URL: https://codeforces.com/contest/1901/problem/0
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second 
#define endl '\n'
const LL maxn = 4e05+7;
const LL N=1e05+10;
const LL mod=1e09+7;
typedef pair<int,int>pl;
priority_queue<LL , vector<LL>, greater<LL> >t;
priority_queue<LL> q;
LL gcd(LL a, LL b){return b > 0 ? gcd(b , a % b) : a;
}LL lcm(LL a , LL b){return a / gcd(a , b) * b;
}
int n , m;
int a[N];
void init(int n){for(int i = 0 ; i <= n ; i ++){a[i] = 0;}
}
void solve() 
{cin >> n >> m;for(int i = 1 ; i <= n ; i ++){cin >> a[i];}	int maxx = (m - a[n]) * 2;for(int i = 1 ; i <= n ;i ++){maxx = max(maxx , a[i] - a[i - 1]);}cout << maxx << endl;
}            
int main() 
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cout.precision(10);int t=1;cin>>t;while(t--){solve();}return 0;
}

B - Chip and Ribbon 

        题意:有一条带子被分成 n 个单元格,从左到右编号为 1 到 n 。最初,每个单元格中都写有一个整数 0。Monocarp在玩芯片游戏。游戏由几个回合组成。在第一轮中,Monocarp 将芯片放入色带的 第一单元格。除了第一轮之外,在每一轮中,魔卡都会做以下两个动作中的恰好一个:

  • 将芯片移动到下一个单元格(例如,如果芯片在 i 单元格,则将其移动到 i+1单元格)。如果芯片在上一格,则无法进行此操作;
  • 选择任意一个 x单元格,将芯片传送到该单元格。可以选择芯片当前所在的单元格

每回合结束时,写入芯片所在单元格的整数会增加 1。

Monocarp的目标是在某些回合中使第一个单元格中等于整数 c1 , 第二个单元格中等于整数 c2 ....第n个单元格中等于整数 cn。他希望尽可能少地传送芯片。

请帮助 Monocarp 计算他传送芯片的最少次数。

        思路:对于一个连续的序列来说,无需传送就能全部+1,因此此题变成了每轮操作能将[l ,r]单元格内的数加一,求最小操作数。此题类似于Problem - C - Codeforces

可以发现,所有左侧标红的即为选择的区间,因此最小操作数就是统计标红的数量,即\sum _{i = 1}^{n}max(0 , a[i] - a[i - 1])。具体解析可以看该题题解。

        

// Problem: B. Chip and Ribbon
// Contest: Codeforces - Educational Codeforces Round 158 (Rated for Div. 2)
// URL: https://codeforces.com/contest/1901/problem/B
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second 
#define endl '\n'
const LL maxn = 4e05+7;
const LL N=2e05+10;
const LL mod=1e09+7;
typedef pair<int,int>pl;
priority_queue<LL , vector<LL>, greater<LL> >t;
priority_queue<LL> q;
LL gcd(LL a, LL b){return b > 0 ? gcd(b , a % b) : a;
}LL lcm(LL a , LL b){return a / gcd(a , b) * b;
}
int n , m;
int a[N];
void init(int n){for(int i = 0 ; i <= n ; i ++){a[i] = 0;}
}
void solve() 
{int n;cin >> n;for(int i = 1 ; i <= n ; i ++){cin >> a[i];}	LL ans = 0;for(int i = 1 ; i <= n ; i ++){if(a[i] > a[i - 1]){ans += a[i] - a[i - 1];}}cout << ans - 1<< endl;
}            
int main() 
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cout.precision(10);int t=1;cin>>t;while(t--){solve();}return 0;
}

C - Add, Divide and Floor 

        题意:给你一个整数数组 a1,a2,…,an ( 0\leq a_{i}\leq 10^9 )。在一次操作中,你可以选择一个整数 x ( 0\leq x\leq 10^{18} ),并用 ⌊(a_{i} + x ) / 2⌋ 替换 ai ( ⌊y⌋ 表示将 y 舍入为最接近的整数)。 ⌊y⌋ 表示将 y 舍入为最接近的整数)来替换从 1 到 n 的所有 i。请注意,每次操作都会影响数组中的所有元素。打印使数组中所有元素相等所需的最小操作数。如果操作次数小于或等于 n,则打印每次操作所选择的 x 。如果有多个答案,则打印任意一个。

        思路:若最小的数通过操作等于最大的数,那么其他数必然也相等。因此只需要看最小的和最大的即可。再考虑如何去操作:观察可以发现其实x的大小没有用,x的奇偶性可能会改变答案,因此我们x的取值只设为(0 , 1)。如果最大值是偶数,那么+1不会使得结果更大,否则可能会使得结果更大。

        

// Problem: C. Add, Divide and Floor
// Contest: Codeforces - Educational Codeforces Round 158 (Rated for Div. 2)
// URL: https://codeforces.com/contest/1901/problem/C
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second 
#define endl '\n'
const LL maxn = 4e05+7;
const LL N=2e05+10;
const LL mod=1e09+7;
typedef pair<int,int>pl;
priority_queue<LL , vector<LL>, greater<LL> >t;
priority_queue<LL> q;
LL gcd(LL a, LL b){return b > 0 ? gcd(b , a % b) : a;
}LL lcm(LL a , LL b){return a / gcd(a , b) * b;
}
int n , m;
int a[N];
void init(int n){for(int i = 0 ; i <= n ; i ++){a[i] = 0;}
}
void solve() 
{cin >> n;int maxx = -1 , minn = 1.5e9;for(int i = 0 ; i < n ; i ++){cin >> a[i];maxx = max(a[i] , maxx);minn = min(minn , a[i]);}vector<int> ans;while (minn != maxx) {if (minn % 2 == maxx % 2) {ans.push_back(0);} else if (maxx % 2 == 0) {ans.push_back(1);++minn;++maxx;} else {ans.push_back(0);}minn /= 2;maxx /= 2;}cout << ans.size() << "\n";if ((int)ans.size() <= n) {for (int x : ans) {cout << x << " ";}cout << "\n";}
}            
int main() 
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cout.precision(10);int t=1;cin>>t;while(t--){solve();}return 0;
}

D - Yet Another Monster Fight 

        题意:现有n头怪兽,每个怪兽有a_{i}的血量,你需要发动一次魔法将所有怪兽打败。魔法规则如下:第一轮将打中你选择的那头怪兽,并扣除x的血量,接下来每一轮魔法的伤害值减一,并且打中那些未被打中的,处于已被打中的怪兽的相邻怪兽。要求你可以选择任意第一轮打中的怪兽的情况下,魔法的初始伤害的最小值。

        思路:首先考虑已知第一轮打中第 i 只怪兽的情况下,魔法初始伤害的最小值。对于[1 , i - 1]的第x只怪兽而言,其最晚被打中的轮次为右边所有怪兽的数量(n - x),所以初始伤害值需要a_{i} + n - x,我们将其定义为r[x]。而对于[i + 1 , n]的第j只怪兽而言则相反,其最晚被打中的轮次为j - 1,初始伤害值需要a_{i} + j - 1  ,我们将其定义为l[j]。因此魔法初始伤害的最小值为:max(max(r[1]...r[i - 1]) , a[i] , max(l[i + 1] ...l[n]))。考虑完这个以后我们可以通过前缀最大值和后缀最大值来维护r , l数组。然后再遍历每只怪兽,假设其为第一轮攻击的怪兽,求魔法初始伤害的最小值即可。

        

// Problem: D. Yet Another Monster Fight
// Contest: Codeforces - Educational Codeforces Round 158 (Rated for Div. 2)
// URL: https://codeforces.com/contest/1901/problem/D
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second 
#define endl '\n'
const LL maxn = 4e05+7;
const LL N=3e05+10;
const LL mod=1e09+7;
typedef pair<int,int>pl;
priority_queue<LL , vector<LL>, greater<LL> >t;
priority_queue<LL> q;
LL gcd(LL a, LL b){return b > 0 ? gcd(b , a % b) : a;
}LL lcm(LL a , LL b){return a / gcd(a , b) * b;
}
int n , m;
LL a[N];
LL r[N] , l[N];
void init(int n){for(int i = 0 ; i <= n ; i ++){a[i] = 0;}
}
void solve() 
{int n;cin >> n;for(int i = 1 ; i <= n ; i ++)cin >> a[i];for(int i = 1 ; i <= n ; i ++){l[i] = a[i] + (i - 1);r[i] = a[i] + (n - i);}for(int i = 1 ; i <= n ; i++){r[i] = max(r[i - 1] , r[i]);}for(int i = n; i >= 1 ; i --){l[i] = max(l[i + 1] , l[i]);}LL ans = 1e18;for(int i = 1 ; i <= n ; i ++){ans = min(ans , max(a[i] , max(r[i - 1] ,l[i + 1])));}cout << ans ;
}            
int main() 
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cout.precision(10);int t=1;
//	cin>>t;while(t--){solve();}return 0;
}

E - Compressed Tree (树形DP)

        题意:给你一棵由 n 个顶点组成的树。每个顶点上都写有一个数字;顶点 i 上的数字等于 ai 。

        您可以执行以下任意次数的操作(可能为零):选择一个最多有1条边的顶点,并将该顶点从树中删除。请注意,您可以删除所有顶点。

        完成所有操作后,就可以压缩树了。压缩过程如下。当树中有一个顶点恰好有2条边时,执行以下操作:删除该顶点,用一条边连接其邻居。

        可以看出,如果在压缩过程中有多种选择删除顶点的方法,那么得到的树还是一样的。

        你们的任务是计算在任意次数的上述操作后,求出压缩完树以后的所有顶点的权值之和最大。

        思路:对于一个顶点来说,最终压缩完树以后有4种情况:

1、只保留了自己一个顶点。

2、保留了自己和自己邻边上一个顶点。

3、保留了邻边上的两个顶点。

4、保留了自己和邻边上面2个以上的顶点。(这样在压缩的时候就不会把自己删了)

因此用dp[n][4]来分别表示这四种状态。接下来考虑如何从子顶点上转移,若顶点只有一个子顶点,那么就只有1、2两种情况。如果顶点有两个子顶点,那么就会出现1、2、3三种情况。如果子顶点大于2个的话,那么就需要对子顶点的值进行排序了,肯定是越大的越好。对于情况4,并不是所有的子顶点都需要选择,若子顶点的值小于0,那么就代表这子顶点是无需保留的,删除即可。

        接下来考虑子树的值如何选择:对于情况1和情况4,直接继承。对于情况2,在压缩的过程中会把子树结点给压缩掉,所以需要减去子顶点的值。对于情况3,原本是不保留子顶点的,但是由于需要连到父亲上,所以子顶点需要保留,因此需要增加子顶点的值。因此一个子顶点的值即为:max(dp[ch][1] , dp[ch][2] - a[ch] , dp[ch][3] + a[ch] , dp[ch][4])

        接下来走任意一点开始走一遍DFS,时刻记录最大值。(只有一条链或者两个点的情况下特殊处理一下即可)

// Problem: E. Compressed Tree
// Contest: Codeforces - Educational Codeforces Round 158 (Rated for Div. 2)
// URL: https://codeforces.com/contest/1901/problem/E
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second 
#define endl '\n'
const LL maxn = 4e05+7;
const LL N=5e05+10;
const LL mod=1e09+7;
const LL inf = 1e18;
typedef pair<int,int>pl;
priority_queue<LL , vector<LL>, greater<LL> >t;
priority_queue<LL> q;
LL gcd(LL a, LL b){return b > 0 ? gcd(b , a % b) : a;
}LL lcm(LL a , LL b){return a / gcd(a , b) * b;
}
int n , m;
LL a[N];
int deg[N];
vector<int>e[N];
LL dp[N][4];
void init(int n){for(int i = 0 ; i <= n ; i ++){a[i] = 0 , deg[i] = 0 , e[i].clear();}
}
LL cmp(LL a , LL b){return a > b;
}
LL ans = 0;
void dfs(int cur , int fa){dp[cur][0] = a[cur] , dp[cur][1] = -inf , dp[cur][2] = -inf , dp[cur][3] = -inf;vector<LL>ch;for(auto v : e[cur]){if(v == fa)continue;dfs(v , cur);ch.pb(max(dp[v][0], max(dp[v][1] - a[v], max(dp[v][2] + a[v], dp[v][3]))));}sort(ch.begin() , ch.end() , cmp);if(ch.size() >= 1){dp[cur][1] = a[cur] + ch[0];}if(ch.size() >= 2){dp[cur][2] = ch[0] + ch[1];}if(ch.size() >= 3){dp[cur][3] = a[cur] + ch[0] + ch[1] + ch[2];for(int i = 3 ; i < (int)ch.size() ; i ++){if(ch[i] < 0){break;}dp[cur][3] += ch[i];}}ans = max(ans , max(dp[cur][0], max(dp[cur][1], max(dp[cur][2], dp[cur][3]))));
}
void solve() 
{cin >> n;for(int i = 1 ; i <= n ; i ++)cin >> a[i];int max_deg = 1;for(int i = 1 ; i < n ; i ++){int x , y;cin >> x >> y;e[x].pb(y);e[y].pb(x);deg[x] ++;deg[y] ++;max_deg = max(max_deg , max(deg[x] , deg[y]));}if(max_deg == 1){if(a[1] < 0){cout << max(1LL * 0 , a[2]) << endl;}else{cout << max(a[1] , a[1] + a[2]) << endl;}}else if(max_deg == 2){sort(a + 1, a + 1 + n , cmp);if(a[1] < 0){cout << max(1LL * 0 , a[2]) << endl;}else{cout << max(a[1] , a[1] + a[2]) << endl;}}else{ans = 0;dfs(1 , 0);cout << ans << endl;}init(n);
}            
int main() 
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cout.precision(10);int t=1;cin>>t;while(t--){solve();}return 0;
}

        

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

麒麟linux离线安装dotnet core

1. 下载 dotnet core,以3.1为例 下载地址: 下载 .NET Core 3.1 (Linux、macOS 和 Windows) 查看linux cpu类型,然后根据类型下载 uname -m #结果是: aarch64 2. 放到指定目录,比如:/usr/dotnet 3. 解压dotnet-sdk-3.1.426-linux-arm64.tar.gz cd /usr/dotnet tar –zxvf a…

Ubuntu 22.04.3编译AOSP13刷机

文章目录 设备信息下载AOSP并切换分支获取设备驱动编译系统编译遇到的问题Cannot allocate memoryUbuntu设置USB调试刷机参考链接 设备信息 手机&#xff1a;Pixel 4XL 下载AOSP并切换分支 在清华大学开源软件镜像站下载初始化包aosp-latest.tar。 解压缩&#xff0c;切换到…

解决LocalDateTime传输前端为时间的数组

问题出现如下&#xff1a; 问题出现原因&#xff1a; 默认序列化情况下会使用SerializationFeature.WRITE_DATES_AS_TIMESTAMPS。使用这个解析时就会打印出数组。 解决方法&#xff1a; 我在全文搜索处理方法总结如下&#xff1a; 1.前端自定义函数来书写 ,cols: [[ //表头{…

Langchain的Agents介绍

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

Redis -- 介绍

1、NoSQL: 指的是非关系型数据库&#xff0c;主要分成四大类&#xff1a;键值存储数据库、列存储数据库、文档型数据库、图形数据库。 2、什么是Redis&#xff1a; Redis是一种基于内存的数据库&#xff0c;一般用于做缓存的中间件。 3、Redis的主要的特点&#xff1a; 1、Rd…

一、TIDB基础

TIDB整个逻辑架构跟MYSQL类似&#xff0c;如下&#xff1a; TIDB集群&#xff1a;相当于MYSQL的数据库服务器&#xff0c;区别是MYSQL数据库服务器为单进程的&#xff0c;TIDB集群为分布式多进程的。 数据库&#xff1a;同MYSQL数据库&#xff0c;数据库属于集群&#xff0c;…

SSL握手失败的解决方案

一、SSL握手失败的原因&#xff1a; 1&#xff0c;证书过期&#xff1a;SSL证书有一个有效期限&#xff0c;如果证书过期&#xff0c;就会导致SSL握手失败。 2&#xff0c;证书不被信任&#xff1a;如果网站的SSL证书不被浏览器或操作系统信任&#xff0c;也会导致SSL握手失败…

线性代数的艺术

推荐一本日本网友Kenji Hiranabe写的《线性代数的艺术》。这本书是基于MIT大牛Gilbert Strang教授的《每个人的线性代数》制作的。 虽然《线性代数的艺术》这本书仅仅只有12页的内容&#xff0c;就把线性代数的重点全画完了&#xff0c;清晰明了。 《线性代数的艺术》PDF版本&…

mysql 变量和配置详解

MySQL 中还有一些特殊的全局变量&#xff0c;如 log_bin、tmpdir、version、datadir&#xff0c;在 MySQL 服务实例运行期间它们的值不能动态修改&#xff0c;也就是不能使用 SET 命令进行重新设置&#xff0c;这种变量称为静态变量。数据库管理员可以使用前面提到的修改源代码…

ErphpdownV16.21插件 安装教程和插件下载

ErphpdownV16.21插件下载_新版本 上传插件并解压 登入后台插件管理启动ErphpdownV16.21插件即可 启动后设置即可使用此版本为学习版插件 功能介绍&#xff1a; Erphpdown会员推广下载专业版 经过完美测试运行于wordpress 3.x-6.x版本。后续会增加更多实用的功能。已针对此插件…

Windows IDEA Python开发环境安装+爬虫示例

文章目录 Python下载安装开发工具IDEA包管理安装pip基本用法从 requirements.txt 安装依赖 项目示例部署在 Linux 上安装Python在 Linux 上创建虚拟环境&#xff1a;安装依赖&#xff1a;运行你的爬虫 Python下载安装 Python 安装包下载地址&#xff1a;https://www.python.or…

Oracle登录认证方式详解

文章目录 一、简介二、OS认证三、口令认证四、remote_login_passwordfile 详解 一、简介 在数据库管理中&#xff0c;登录认证是确保数据库安全性的重要环节。Oracle数据库提供 了两种认证方式&#xff0c;一种是“操作系统认证”&#xff0c;一种是“口令文件认证&#xff0c…

智安网络|如何最大限度地提高企业网络安全水平

在当今数字化时代&#xff0c;企业面临着日益复杂和智能化的网络威胁。为了保护企业的机密信息和客户数据&#xff0c;漏洞扫描成为了一个至关重要的安全措施。然而&#xff0c;对于企业来说&#xff0c;他们最关心的是什么问题呢&#xff1f; 一、漏洞的发现和修复 在网络安全…

路径规划之Best-First Search算法

系列文章目录 路径规划之Dijkstra算法 路径规划之Best-First Search算法 路径规划之Best-First Search算法 系列文章目录前言一、Best-First Search算法1.1 起源1.2 过程 三、简单使用 前言 Best-First Search算法和Dijkstra算法类似&#xff0c;都属于BFS的扩展或改进 一、…

基于官方YOLOv4开发构建目标检测模型超详细实战教程【以自建缺陷检测数据集为例】

本文是关于基于YOLOv4开发构建目标检测模型的超详细实战教程&#xff0c;超详细实战教程相关的博文在前文有相应的系列&#xff0c;感兴趣的话可以自行移步阅读即可&#xff1a;《基于yolov7开发实践实例分割模型超详细教程》 《YOLOv7基于自己的数据集从零构建模型完整训练、…

Linux技能篇-非交互式修改密码

今天的文章没有格式&#xff0c;简单分享一个小技能&#xff0c;就是标题所说–非交互式修改密码。 一、普通方式修改用户密码 最普通的修改密码的命令就是passwd命令 [rootlocalhost ~]# passwd root Changing password for user root. New password: Retype new password:…

一文彻底看懂Python切片,Python切片理解与操作

1.什么是切片 切片是Python中一种用于操作序列类型(如列表、字符串和元组)的方法。它通过指定起始索引和结束索引来截取出序列的一部分,形成一个新的序列。切片是访问特定范围内的元素,就是一个Area。 说个笑话:切片不是切片,而是切片,但是又是切片。大家理解下呢(末…

【云原生 Prometheus篇】Prometheus的动态服务发现机制

自动发现 一、Prometheus服务发现 理论部分1.1 Prometheus数据采集配置1.2 基于文件的服务发现1.3 基于consul的服务发现1.4 基于 Kubernetes API 的服务发现1.4.1 概念1.4.2 部分配置参数1.4.3 配置模板 二、实例一&#xff1a;部署基于文件的服务发现2.1 创建用于服务发现的文…

uniapp 轮播图(含组件封装,自动注册全局组件)

效果预览 组件封装 src\components\SUI_Swiper.vue 可参考官网配置更多属性 swipernavigator <script setup lang"ts"> import { ref } from vue defineProps({config: Object, })const activeIndex ref(0) const change: UniHelper.SwiperOnChange (e) &…

一起学docker系列之八使用 Docker 安装配置 MySQL

目录 前言步骤 1&#xff1a;拉取 MySQL 镜像步骤 2&#xff1a;运行 MySQL 容器步骤 3&#xff1a;检查容器状态步骤 4&#xff1a;进入 MySQL 容器步骤 5&#xff1a;配置 MySQL 字符编码步骤 6&#xff1a;重启 MySQL 容器步骤 7&#xff1a;测试字符编码步骤 8&#xff1a;…