2025.2.8 寒假综合训练赛2题解

A. 博弈

Link:P1290 欧几里德的游戏

博弈类的题目,首先考虑找找有什么性质,从而找到“必胜态”和“必败态”。

其中,面对“必胜态”不一定取胜(看个人操作的好坏),但面对“必败态”一定输(对手不会给你做选择的机会)。

上面两条是明确且标准的定义。我们发现如果你能让对手面对“必败态”,或你可以通过一系列方式(例如通过细化操作控制先后手)使自己面对必胜态,则在双方最优操作的情况下(一般题目都这样要求,不然没法做)你自己是一定能赢的。

同时,根据定义,“必胜态”下一步的所有可能性一定是“必败态”。

以上其实就是简单的一个 sg 函数推导;由“必胜态”一步转化到“必败态”其实就是一个“纳什平衡”点。有兴趣可以自行了解。


下面带入到题目当中。设表示当前局面的状态为 ( x , y ) (x,y) (x,y),我们规定 x ≥ y x \ge y xy

发现题目要求的其实就是求 gcd 的“辗转相除”过程,只不过一次可以减多个 y y y

一个显然的必胜态:若 y ∣ x y \mid x yxx%y==0),显然先手必胜。

然后考虑 x , y x,y x,y 的大小关系:

  1. y ≤ x ≤ 2 y y \le x \le 2y yx2y:此时只能减去一次 y y y,之后先后手互换操作 ( x − y , y ) (x-y,y) (xy,y)。无法确定谁获胜。
  2. x ≥ 2 y x \ge 2y x2y:先手可以减去尽可能多的 y y y,使局面变成 ( x m o d y , y ) (x\ mod\ y, y) (x mod y,y)。也可以少减一个 y y y,让对手操作一次变为 ( x m o d y , y ) (x\ mod\ y, y) (x mod y,y)。无论 ( x m o d y , y ) (x\ mod\ y, y) (x mod y,y) 是先手获胜还是后手获胜,当前操作者都可以改变先后手(即“少减一个y”)使自己获胜。所以此时是必胜态
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;// 如果Stan获胜返回1,否则返回0
int dfs(int x, int y, int now){ // 如果当前该Stan,now=1,否则now=0if(x < y) swap(x, y); // 保证x总比y大if(x % y == 0){return now == 1; // 可以直接赢}if(y <= x && x <= 2 * y){return dfs(x - y, y, now ^ 1); // 只能先操作一次,再看}else if(x >= 2 * y){return now == 1; // 上面说过,当前操作者此时一定可以改变先后手使自己获胜}return -1; // 理论上不会到达这里
}void solve()
{int x, y; cin >> x >> y;puts(dfs(x, y, 1)? "Stan wins" : "Ollie wins");
}signed main()
{ios :: sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);int T; cin >> T;while(T --) solve();return 0;
}

B. 宝石探险家

Link:P6002 (USACO20JAN) Berry Picking S

背景:这道题没有一个人赛时满分,CD题都有人过,很多人被这道题卡在了 AK 的半路上。然而老师说做法特别简单?实际上也是这样的,看来是我们太蒟了。。。

进入正题:

发现每个树上最多有 1000 1000 1000 个果子,所以我们可以考虑枚举一个答案 x x x,保证要给对手的 k 2 \frac{k}{2} 2k 个篮子里的最小值为 x x x,这也就同时限制了给自己留下的 k 2 \frac{k}{2} 2k 个篮子里的最大值为 x x x

考虑分情况讨论:

  1. 我们能取出 k k k x x x,那么显然这 k k k 个袋子里装的都是 x x x,我们留给自己的答案应该是 k 2 ⋅ x \frac{k}{2} \cdot x 2kx
  2. 我们怎么取都取不出 k 2 \frac{k}{2} 2k x x x,那么显然直接无解,跳过这个情况。
  3. 我们可以取出一部分完整的 x x x,但不够给自己分( k 2 < ⌊ k x ⌋ < k \frac{k}{2} < \lfloor\frac{k}{x}\rfloor < k 2k<xk<k)。这时候我们会把 k 2 \frac{k}{2} 2k 个完整的 x x x 给对方,然后给自己尽可能多的完整的 x x x,如果不够就在剩下的余数里挑大的给自己。

第三种情况维护余数可以考虑用优先队列实现。

时间复杂度 O ( n 2 log ⁡ n ) O(n^2 \log n) O(n2logn)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;int n, k, a[1005];void solve()
{cin >> n >> k;for(int i = 1; i <= n; i ++){cin >> a[i];}int ans = 0;for(int x = 1, maxx = *max_element(a + 1, a + n + 1); x <= maxx; x ++){ // 枚举中间点int tot = 0; // 统计能拆出来多少个完整的xpriority_queue <int> Q; // 记录余数for(int i = 1; i <= n; i ++){tot += a[i] / x;Q.push(a[i] % x);}if(tot < k / 2) continue; // 无解if(tot >= k){ans = max(ans, x * (k / 2)); continue; // 足够分,直接对半}int cnt = 0; // 记录自己能拿到的个数cnt += (tot - k / 2) * x; // 先把完整的x算上for(int i = 1; i <= k - tot; i ++){ // 选的个数:k/2-(tot-k/2)=k-totcnt += Q.top(); Q.pop();}ans = max(ans, cnt);}cout << ans << '\n';
}signed main()
{ios :: sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);solve();return 0;
}

C.星际能量站

Link:P3146 (USACO16OPEN) 248 G

看到“合并”这个套路,加上 n n n 很小,不难想到区间 dp。

f i , j f_{i,j} fi,j 表示融合区间 [ i , j ] [i,j] [i,j] 可以获得的最高频率。

转移考虑枚举一个断点 k ( i ≤ k < j ) k\ (i \le k < j) k (ik<j),若 f i , k = f k + 1 , j f_{i,k}=f_{k+1,j} fi,k=fk+1,j,则f[i][j]可以合并成一个新的值,尝试转移 f i , k + 1 f_{i,k}+1 fi,k+1

然后, [ i , j ] [i,j] [i,j] 还可以由两个小区间的答案合并得来,尝试转移 max ⁡ { f i , k , f k + 1 , j } \max\{f_{i,k},f_{k+1,j}\} max{fi,k,fk+1,j}

但这样会有问题,我们会把 [ 2 , 6 , 2 ] [2,6,2] [2,6,2] 这样原来无法合并的区间看成了一个单独的 6 6 6!这显然是会影响答案的(看注释掉的那一行转移)

考虑修改状态的定义, f i , j f_{i,j} fi,j 表示如果 [ i , j ] [i,j] [i,j] 可以融合成一个数的话能得到的最高频率。
那么,对于无法合并成一个的(例如 [ 2 , 6 , 2 ] [2,6,2] [2,6,2] f f f 值会是 − ∞ - \infty
这样定义状态的话,答案应该是所有 f i , j f_{i,j} fi,j 的最大值 max ⁡ 1 ≤ i ≤ j ≤ n f i , j \max \limits_{1 \le i \le j \le n} f_{i,j} 1ijnmaxfi,j

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;int n, ans = -1e9;
int a[250];
int f[250][250]; // f[i][j]: 融合区间[i,j]可以获得的最高频率void solve()
{memset(f, -0x3f, sizeof f);cin >> n;for(int i = 1; i <= n; i ++){cin >> a[i];f[i][i] = a[i]; // 融合长度为1的区间,得到的只能是a[i]本身ans = max(ans, f[i][i]);}for(int l = 2; l <= n; l ++){for(int i = 1; i + l - 1 <= n; i ++){int j = i + l - 1;for(int k = i; k <= j - 1; k ++){if(f[i][k] == f[k + 1][j]){f[i][j] = max(f[i][j], f[i][k] + 1);}
//              f[i][j] = max(f[i][j], max(f[i][k], f[k + 1][j])); // 不能转移}ans = max(ans, f[i][j]);}}cout << ans << '\n';
}signed main()
{ios :: sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);solve();return 0;
}

这道题还有一个加强版:P3147 (USACO16OPEN) 262144 P,数据更极限,用的是用倍增思想进行区间 dp 的trick,有兴趣可以了解一下。

D.量子仓库

Link:P3052 (USACO12MAR) Cows in a Skyscraper G

发现这道题有一个显然的暴力就是用全排列上手,枚举全排列,然后按照顺序每次都尽可能装接近 W W W 的物品传送。

但这样时间复杂度是指数级别的。Sheryang 说过:全排列能做的题大多都可以用状压优化复杂度。

这道题的 n ≤ 18 n \le 18 n18,也很小,所以就考虑状压 dp。

f [ i ] [ j ] f[i][j] f[i][j] 表示当前用了 i i i 组,选择状态为 j j j 时当前电梯里的最小重量。

那么答案就是最小的存在 f [ i ] [ 2 n − 1 ] f[i][2^n-1] f[i][2n1] 方案的 i i i

考虑转移,如果物品 k k k 可以放在当前这一组里,且容量满足限制 f [ i ] [ j ] + c [ k ] ≤ W f[i][j] + c[k] \le W f[i][j]+c[k]W,就可以继续往这一组里放:
f [ i ] [ j ∣ ( 1 < < k ) ] = m i n ( f [ i ] [ j ∣ ( 1 < < k ) ] , f [ i ] [ j ] + c [ k ] ) f[i][j\ | \ (1<<k)] = min(f[i][j\ | \ (1<<k)],\ f[i][j] + c[k]) f[i][j  (1<<k)]=min(f[i][j  (1<<k)], f[i][j]+c[k])
如果这一组不够 f [ i ] [ j ] + c [ k ] > W f[i][j] + c[k] > W f[i][j]+c[k]>W,那么就只能新开一组:
f [ i + 1 ] [ j ∣ ( 1 < < k ) ] = m i n ( f [ i + 1 ] [ j ∣ ( 1 < < k ) ] , c [ k ] ) f[i+1][j\ |\ (1<<k)] = min(f[i+1][j\ |\ (1<<k)],\ c[k]) f[i+1][j  (1<<k)]=min(f[i+1][j  (1<<k)], c[k])
初始化考虑初始化为 + ∞ +\infty +。初状态即为任选一个物品放到第一个袋子中: f [ 1 ] [ 1 < < i ] = c [ i ] f[1][1<<i]=c[i] f[1][1<<i]=c[i]

时间复杂度为 O ( 2 n × n 2 ) O(2^n \times n^2) O(2n×n2)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;int n, W;
int c[20], f[20][1 << 20];void solve()
{memset(f, 0x3f, sizeof f); // 初始化为极大值cin >> n >> W;for(int i = 1; i <= n; i ++){cin >> c[i];}for(int i = 1; i <= n; i ++){ // 初始化只选一个的情况f[1][1 << i-1] = c[i];}for(int i = 0; i <= n; i ++){ // 枚举组数for(int j = 0; j < (1 << n); j ++){ // 枚举已经选了的状态if(f[i][j] == f[0][0]) continue; // 注意判断状态f[i][j]是否存在for(int k = 1; k <= n; k ++){ // 枚举下一个选哪个位置if(j & (1 << k-1)) continue; // 保证k之前没有选过if(f[i][j] + c[k] <= W){f[i][j | (1 << k-1)] = min(f[i][j | (1 << k-1)], f[i][j] + c[k]);}else{f[i + 1][j | (1 << k-1)] = min(f[i + 1][j | (1 << k-1)], c[k]);}}}}for(int i = 0; i <= n; i ++){if(f[i][(1 << n) - 1] != f[0][0]){cout << i << '\n';return ;}}
}signed main()
{ios :: sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);solve();return 0;
}

当然,这道题还有一些神秘做法(比如裸搜剪枝、迭代加深搜索IDDFS,贪心配合模拟退火等),有兴趣请自行移步洛谷题解区~

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

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

相关文章

docker离线安装及部署各类中间件(x86系统架构)

前言&#xff1a;此文主要针对需要在x86内网服务器搭建系统的情况 一、docker离线安装 1、下载docker镜像 https://download.docker.com/linux/static/stable/x86_64/ 版本&#xff1a;docker-23.0.6.tgz 2、将docker-23.0.6.tgz 文件上传到服务器上面&#xff0c;这里放在…

Spring Boot 中的日志配置

文章目录 Spring Boot 中日志配置的源码分析1. Spring Boot 日志框架的选择与自动配置2. 日志自动配置与默认行为3. 日志系统的核心组件&#xff1a;Logger 和 LoggerFactory4. 日志配置文件的解析配置日志级别配置日志输出格式和目标 5. 日志级别的控制自定义日志级别 6. 自定…

从零到一:我的元宵灯谜小程序诞生记

缘起&#xff1a;一碗汤圆引发的灵感 去年元宵节&#xff0c;我正捧着热腾腾的汤圆刷朋友圈&#xff0c;满屏都是"转发锦鲤求灯谜答案"的动态。看着大家对着手机手忙脚乱地切换浏览器查答案&#xff0c;我突然拍案而起&#xff1a;为什么不做一个能即时猜灯谜的微信…

CSS3+动画

浏览器内核以及其前缀 css标准中各个属性都要经历从草案到推荐的过程&#xff0c;css3中的属性进展都不一样&#xff0c;浏览器厂商在标准尚未明确的情况下提前支持会有风险&#xff0c;浏览器厂商对新属性的支持情况也不同&#xff0c;所有会加厂商前缀加以区分。如果某个属性…

2025.2.8——二、Confusion1 SSTI模板注入|Jinja2模板

题目来源&#xff1a;攻防世界 Confusion1 目录 一、打开靶机&#xff0c;整理信息 二、解题思路 step 1&#xff1a;查看网页源码信息 step 2&#xff1a;模板注入 step 3&#xff1a;构造payload&#xff0c;验证漏洞 step 4&#xff1a;已确认为SSTI漏洞中的Jinjia2…

c++初始

目录 一数据类型 1. 2.sizeof 3.布尔 4.字符串类型 二.数据输入与输出 1.输出 2.输入 三.运算 1.加减乘除取模&#xff0c;&#xff0c;--都一样 2.逻辑非与或&#xff0c;与C语言一样 3.比较运算符&#xff0c;与C语言一样 4.三目运算符&#xff08;与C语言一样&a…

数字电路-基础逻辑门实验

基础逻辑门是数字电路设计的核心元件&#xff0c;它们执行的是基本的逻辑运算。通过这些基本运算&#xff0c;可以构建出更为复杂的逻辑功能。常见的基础逻辑门包括与门&#xff08;AND&#xff09;、或门&#xff08;OR&#xff09;、非门&#xff08;NOT&#xff09;、异或门…

HC32功能复用说明

目录 引脚有哪些功能如何选择功能代码 引脚有哪些功能 数据手册中&#xff0c;每一个引脚功能有至多64个&#xff0c;对应列Func0~Func63 其中&#xff0c;Func0 ~Func31在《表 2-1 引脚功能表》中列出 Func32~Func63在《表 2-2 Func32~63 表》中列出。 Func32~Func63中的功…

数据库管理-第293期 奇怪的sys.user$授权+(20250210)

数据库管理293期 2025-02-10 数据库管理-第293期 奇怪的sys.user$授权&#xff08;20250210&#xff09;1 清空shared pool2 SR反馈总结 数据库管理-第293期 奇怪的sys.user$授权&#xff08;20250210&#xff09; 作者&#xff1a;胖头鱼的鱼缸&#xff08;尹海文&#xff09…

AutoMQ 如何实现没有写性能劣化的极致冷读效率

前言 追赶读&#xff08;Catch-up Read&#xff0c;冷读&#xff09;是消息和流系统常见和重要的场景。 削峰填谷&#xff1a;对于消息来说&#xff0c;消息通常用作业务间的解耦和削峰填谷。削峰填谷要求消息队列能将上游发送的数据堆积住&#xff0c;让下游在容量范围内消费…

【大模型】本地部署DeepSeek-R1:8b大模型及搭建Open-WebUI交互页面

本地部署DeepSeek-R1:8b大模型 一、摘要及版本选择说明1.1 摘要1.2 版本选择 二、下载并安装Ollama三、运行DeepSeek-R1:8b大模型四、安装Open WebUI增强交互体验五、关闭Ollama开机自动启动六、DeepSeek大模型启停步骤 一、摘要及版本选择说明 1.1 摘要 作为一名对 AI 和生成…

DeepSeek大模型的发展的十问十答

DeepSeek大模型是由杭州深度求索人工智能基础技术研究有限公司开发的一款基于Transformer架构的大型语言模型&#xff0c;具体介绍如下&#xff1a; 1. 架构基础 Transformer架构&#xff1a;DeepSeek大模型基于Transformer架构&#xff0c;该架构由Google在2017年提出&#xf…

Avnet RFSoC基于maltab得5G 毫米波 开发工具箱

使用 MATLAB 连接到 AMD Zynq™ RFSoC 评估板。使用 RF 附加卡执行 OTA 测试。使用 HDL Coder 部署算法 版本要求&#xff1a; 大于 2023b 需要以下支持包之一&#xff1a; 适用于 Xilinx 基于 Zynq 的无线电&#xff08;R2023b 及更早版本&#xff09;的通信工具箱支持包适…

directx12 3d开发过程中出现的报错 九

报错&#xff1a; ThrowIfFailed(md3dDevice->CreateGraphicsPipelineState(&basePsoDesc, IID_PPV_ARGS(&mPSO))); 参数错误 当 md3dDevice->CreateGraphicsPipelineState 调用返回 “参数错误” 时&#xff0c;意味着传递给该函数的 D3D12_GRAPHICS_PIPELINE_…

计算机毕业设计Python+Spark知识图谱医生推荐系统 医生门诊预测系统 医生数据分析 医生可视化 医疗数据分析 医生爬虫 大数据毕业设计 机器学习

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

Vue事件处理 - 绑定事件

Vue 渐进式JavaScript 框架 基于Vue2的学习笔记 - Vue事件处理 - 绑定事件及事件处理 目录 事件处理 绑定方式 函数表达式 绑定函数名 输入框绑定事件 拿到输入框的值 传值加事件源 事件第三种写法 总结 事件处理 绑定方式 函数表达式 在按钮上使用函数表达式绑定事…

World of Warcraft [CLASSIC] 80 Four Horsemen (Naxxramas)

纳克萨玛斯 天启四骑士 Four Horsemen 图一&#xff1a;10人同生共死 图二&#xff1a;25人同生共死站位 图三&#xff0c;不做同生共死&#xff0c;做永恒者&#xff0c;击杀白马分布图&#xff0c;主要是不熟练乱跑&#xff0c;容易导致减员失败 永恒者&#xff0c;玩家无一…

DeepSeek与AI提示语设计的全面指南

当人人都会用AI时&#xff0c;你如何用得更好更出彩&#xff1f;本文全面介绍了DeepSeek的功能与使用方法&#xff0c;并深入探讨了AI提示语设计的核心技巧与进阶策略。通过精准的任务定义、提示语优化和人机协作&#xff0c;用户可以从AI的基础使用逐步进阶到创新应用&#xf…

DeepSeek-R1两种不同模型变体(deepseek-llm-7b-chat 和 deepseek-llm-7b-base)之间的区别

deepseek-llm-7b-chat 和 deepseek-llm-7b-base 是基于同一参数量级&#xff08;7B&#xff09;的两种不同模型变体&#xff0c;主要区别在于训练目标、适用场景和性能表现。以下是详细对比&#xff1a; 1. 核心区别 特性deepseek-llm-7b-basedeepseek-llm-7b-chat训练目标通用…

HarmonyOS Next 方舟字节码文件格式介绍

在开发中&#xff0c;可读的编程语言要编译成二进制的字节码格式才能被机器识别。在HarmonyOS Next开发中&#xff0c;arkts会编译成方舟字节码。方舟字节码长什么样呢&#xff1f;我们以一个demo编译出的abc文件&#xff1a; 二进制就是长这样&#xff0c;怎么去理解呢&…