当前位置: 首页 > news >正文

【CF】Day148——Codeforces Round 1057 (Div. 2) CD (非退化凸多边形的分类讨论 | 破环成链动态规划)

C. Symmetrical Polygons

题目:

思路:

非退化

我们本题不难看我们可以选取所有的偶数边,同时对于奇数边我们可以选取 x - 1 条变成偶数条边

那么最后的关键点就是能否再选边?这是显然的,我们最多还能再选两条单边

所以分类讨论

①.选一条单边

那么就有这条单边必须小于其余边长之和

②.选两条单边

同上,但是我们只需要考虑较长边

③.不额外选

此时我们只需要判断任意一条边是否大于其余边之和即可

具体实现看代码

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define yes cout << "YES\n"
#define no cout << "NO\n"
mt19937_64 rnd(chrono::steady_clock::now().time_since_epoch().count());void solve()
{int n;cin >> n;vector<int> a(n + 1);map<int, int> mp;for (int i = 1; i <= n; i++){cin >> a[i];mp[a[i]]++;}int base = 0;vector<int> odd, even;for (auto &[val, cnt] : mp){base += val * (cnt / 2);if (cnt & 1)odd.push_back(val);elseeven.push_back(val);}if (base == 0){cout << "0\n";return;}int ans = 0;for (auto &x : odd){//总长 > 最长单边if (base * 2 > x){ans = max(ans, 2 * base + x);}}for (int i = 1; i < odd.size(); i++){//总长 > 最长单边if (odd[i - 1] + 2 * base > odd[i]){ans = max(ans, 2 * base + odd[i] + odd[i - 1]);}}for (auto& x : even){//总长 > 最长单边(2*base - x > x => 2*base > 2*x => base > x)//但是感觉实际是判断是不是只有两条边,因为如果可以 base > x 恒成立if (base > x){ans = max(ans, 2 * base);}}cout << ans << endl;
}signed main()
{cin.tie(0)->sync_with_stdio(0);int t = 1;cin >> t;while (t--){solve();}return 0;
}

D. Not Alone

题目:

思路:

经典性质

注意到对于该操作,假设最后有一段长为 len 的漂亮数组,那么其可以分割为 2x+3y 的形式,即 x 个长 2 的数组 + y 个长为 3 的数组


证明:对于任意长 len 的漂亮数组(len > 3),我们可以取最后两个数,那么就有以下变化

\sum_{i=1}^{len}|a[i] - x| \rightarrow \sum_{i=1}^{len-2}|a[i] - x| + |a[len] - a[len - 1]|

可以发现原来最后两项的价值为 |a[len]-x|+|a[len-1]-x|,那么只有当 x 为最后两个数中的一个时,才有

\sum_{i=1}^{len}|a[i] - x| = \sum_{i=1}^{len-2}|a[i] - x| + |a[len] - a[len - 1]|

所以我们拿出最后两个数显然是不劣的


那么考虑dp,先考虑简单情况下如果没有环形这个条件如何转移

定义 dp[i] 为处理完前 i 个数的最小操作数,那么就有以下转移

dp[i] = min(dp[i-2] + cost,dp[i-3] + cost)

其中 cost 代表 二块/三块 的最小操作数,那么现在考虑环形

常见操作是破环成链,所以我们枚举破环的位置即可,但是由于本题的块的长度最多为 3,所以我们只需要多枚举 3 个破环点即可,即 (1,2)(2,3)(3,4) 这几个点即可

但实际上只需要多枚举两个即可,即(1,2)(2,3),因为只有(n-1,n,1)(n,1)(n,1,2)这几种组合方式是以 1 开头的情况下没考虑到的

具体的就是将数组全体往左平移一位即可,具体实现看代码

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define yes cout << "YES\n"
#define no cout << "NO\n"
mt19937_64 rnd(chrono::steady_clock::now().time_since_epoch().count());inline int cost(int x, int y) { return abs(x - y); }inline int cost(int x, int y, int z) { return max({x, y, z}) - min({x, y, z}); }void solve()
{int n;cin >> n;vector<int> a(n + 1);for (int i = 1; i <= n; i++){cin >> a[i];}int ans = 1e18;vector<int> dp(n + 1, 0);auto update = [&]() -> void{dp[0] = 0, dp[1] = 1e18;for (int i = 2; i <= n; i++){dp[i] = dp[i - 2] + cost(a[i - 1], a[i]);if (i >= 3)dp[i] = min(dp[i], dp[i - 3] + cost(a[i - 2], a[i - 1], a[i]));}ans = min(ans, dp[n]);};auto aswap = [&]() -> void{for (int i = 2; i <= n; i++)swap(a[i], a[i - 1]);};for (int i = 0; i < 3; i++){update();aswap();}cout << ans << endl;
}signed main()
{cin.tie(0)->sync_with_stdio(0);int t = 1;cin >> t;while (t--){solve();}return 0;
}

http://www.dtcms.com/a/469819.html

相关文章:

  • 网站建设教程金旭亮wordpress自动加p标签
  • 使用C#代码将ODT转换为PDF文件
  • 【网络编程】详解 IP 协议:报头字段、路由器功能、网段划分和分片传输
  • 大模型微调 SFTTrainer 数据处理与训练器配置解析(116)
  • gtest简单应用
  • 访答知识库,企业知识库,访答浏览器,Al编辑器,RAG,Pdf转word。个人知识库,访答RAG,云知识库,私有知识库……
  • 通过企业画册宣传_网络网站建设_新闻媒体合作等方式_企业营销网站制作
  • BERT相关知识自测
  • 【完整源码+数据集+部署教程】 真菌孢子图像分割系统源码&数据集分享 [yolov8-seg-convnextv2等50+全套改进创新点发刊_一键训练
  • 遵义市网站制作如何申请域名网站注册
  • GitHub 热榜项目 - 日榜(2025-10-11)
  • MySQL数据库之DBA命令
  • 4.打造个人Z-Library镜像
  • CoRL-2025 | 物体相对控制赋能具身导航!ObjectReact:学习用于视觉导航的物体相对控制
  • 长春seo网站优化做企业网站接单
  • word超链接网站怎么做网站建设网页设计网站模板
  • spring boot 整合 activiti 教程
  • 免费网站电视剧下载不支持下载的视频怎么保存下来
  • 接口自动化测试流程、工具与实践
  • 【C++继承】深入浅出C++继承机制
  • Mysql杂志(三十一)——Join连接算法与子查询、排序优化
  • HashMap - 底层原理
  • Python第二次作业
  • Vspy使用教程
  • 通用网站模板网站备案要幕布照
  • 网站三要素关键词 描述怎么做青海项目信息网官网
  • JavaScript学习笔记(二十八):JavaScript性能优化全攻略
  • mooc自动互评脚本笔记---2025年10月11日
  • 什么是语言模型
  • 免费网站正能量不用下载网站程序是什么?