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

CF2232D题解

传送门:https://www.luogu.com.cn/problem/CF2232D

题意:汉诺塔变种问题,第 \(i\) 层当且仅当上方有 \(a_i\) 层才能被移动。

照搬汉诺塔的做法显然不可行。进一步发掘性质:一层蛋糕是否能搬动只和上面的蛋糕有关。

我们可以优先搬动最后一层蛋糕到 \(3\) 号柱。在此之前需要先把前 \(a_n\) 层蛋糕移动到 \(2\) 号柱。

如果不能做到问题显然无解,否则我们把第 \(n\) 层移动到 \(3\) 号柱后把前 \(a_n\) 个柱子还原移动到 \(1\) 号柱,因为 \(n\) 层是最大的且已经移动到 \(3\) 号目标柱,所以不会对复原后的 \(n-1\) 个柱子产生任何影响。我们再以相同的手法从大到小依次处理剩下的 \(n-1\) 层即可。

我们根据上述步骤发现有解当且仅当所有的 \(a_i<i\)

具体实现:

设当前的递归状态 \(f_{i,src,tar}\)。表示将前 \(i\) 层从 \(src\) 柱移动到 \(tar\) 柱。

初始 \(f_{n,1,3}\)

  1. 将前 \(a_i\) 层移动到过渡柱,递归 \(f_{a_i,src,src\oplus tar}\)
  2. \(src\) 移动最后一层 \(i\)\(tar\)
  3. 接着还原前 \(a_i\) 层,递归\(f_{a_i,src\oplus tar,src}\)
  4. 最后移动剩下 \(i-1\) 层,递归 \(f_{i-1,src,tar}\)

跑一遍代码发现在样例的标准的 \(3\) 层汉诺塔问题用了 \(13\) 步。

我们分析一下次数,设 \(g_i\) 表示前 \(i\) 次花的步数。

标准汉诺塔问题下我们的算法:\(g_i=2*g_{i-1}+g_{i-1}+1\) 远大于标准汉诺塔的:\(g_i=2*g_{i-1}+1\)

我们发现导致问题的根本原因是我们做了一次冗余的复原即第三步,我们完全可以在过渡柱上处理完整的前 \(i\) 个柱子的子问题,只有当 \(a_i\neq i-1\) 时移动柱子不完整时再复原。

新的步骤:

  1. 将前 \(a_i\) 层移动到过渡柱,递归 \(f_{a_i,src,src\oplus tar}\)
  2. \(src\) 移动最后一层 \(i\)\(tar\)
    • 如果 \(a_i\neq i-1\) 还原前 \(a_i\) 层,递归\(f_{a_i,src\oplus tar,src}\)
    • 否则跳过第 \(4\) 步直接递归 \(f_{i-1,src\oplus tar,src}\)
  3. 最后移动剩下 \(i-1\) 层,递归 \(f_{i-1,src,tar}\)

再次分析次数:

\[g_i=\begin{cases}g_i=2*g_{i-1}+1 & a_i=i-1 \\ g_i=2*g_{a_i}+g_{i-1}+1 &a_i< i-1 \end{cases} \]

应用数学归纳法:

\(h_i\) 是标准汉诺塔前 \(i\) 层的最小移动次数。有递归式 \(h_i=h_{i-1}*2+1\),也有通项公式 \(h_i=2^i-1\)

\(h_0=g_0=0,h_1=g_1=1\)。有\(g_0\leq h_0,g_1\leq h_1\)

对于 \(i\geq 2\)

已知第 \(i-1\) 层满足 \(g_{i-1}\leq h_{i-1}\)

  • 如果 \(a_i=i-1\)

\[\begin{align*}g_i&=g_{i-1}*2+1\\ g_i&\leq h_{i-1}*2+1\\ g_i&\leq h_i \end{align*} \]

  • 如果 \(a_i<i-1\)

\[g_{a_i}\leq g_{i-2} \]

\[\because h_j=h_{j-1}*2+1\ \ \therefore h_{j-1}\leq\frac{h_j-1}{2} \]

\[g_{a_i}\leq g_{i-2}\leq\frac{h_{i-1}-1}{2} \]

\[\begin{align*}g_i&=2*g_{a_i}+g_{i-1}+1\\ g_i&\leq 2*g_{a_i}+h_{i-1}+1\\ g_i&< h_{i-1}*2+1\\ g_i&<h_i\end{align*} \]

综上 \(h_i=2^i-1\geq g_i\) 恒成立。\(\square\)

#include <bits/stdc++.h>using namespace std;int a[21];vector<pair<pair<int, int>, int> > ans;void dfs(int x, int src, int tar) {if (!x) return;if (x == 1) return ans.push_back(make_pair(make_pair(x, src), tar));dfs(x - a[x] - 1, src, src ^ tar);ans.push_back(make_pair(make_pair(x, src), tar));if (!a[x]) dfs(x - 1, src ^ tar, tar);else dfs(x - a[x] - 1, src ^ tar, src), dfs(x - 1, src, tar);
}void solve() {int n;cin >> n;for (int i = 1; i <= n; ++i) cin >> a[i];for (int i = 1; i <= n; ++i) if (a[i] >= i) return cout << "NO\n", void();dfs(n, 1, 3);cout << "YES\n" << ans.size() << '\n';for (auto k: ans) cout << k.first.first << ' ' << k.first.second << ' ' << k.second << '\n';ans.clear();
}int main() {ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int T;cin >> T;while (T--) solve();return 0;
}
http://www.jsqmd.com/news/1033338/

相关文章:

  • 3分钟了解:如何用openpilot开源系统让你的汽车秒变智能驾驶座驾
  • Nitronic60不锈钢选材指南:如何识别靠谱的UNS S21800优质供应商 - 品牌2026
  • 架构师视界 | 基于 Docker 的全栈边缘计算视频中台:解耦 GB28181/RTSP 协议,源码交付如何助力企业节省 95% 开发成本?
  • Node.js爬虫技术革命:x-crawl如何用AI解决90%的动态网页采集难题
  • Reddit视频自动生成器终极指南:一条命令创造百万播放视频
  • Ubuntu终端效率革命:从Terminator到ZSH的完整配置指南
  • 2026年6月!绍兴做GEO优化的公司怎么选?5个判断标准避坑不踩雷 - 936品牌测评网
  • CodeWarrior IDE 5.7菜单系统全解析:从项目构建到嵌入式调试
  • 生成式 UI:AI 驱动的动态界面构建与组件组合推理
  • 为什么越干净的价格数据,越让机器学习模型亏钱?
  • 扣子 3.0 正式上线,但我更关心的是:Agent 做出来之后去哪卖?
  • 国内靠谱的AI智能体软件哪家好
  • 常用类的概念.
  • 5步实战部署DeepCode:从零构建AI智能体编程平台
  • SHAP解释性实战:从原理到电信流失预测的全流程避坑指南
  • 什么是离散化及其实现方式
  • Visual C++运行库终极解决方案:AIO一键修复Windows程序运行问题
  • 为什么你的Figma设计效率提升50%?3个中文界面快速切换秘诀
  • RDP Wrapper终极指南:免费解锁Windows家庭版远程桌面多用户并发连接
  • GB/T 4857.17-2017标准简介
  • 客户流失预警模型:RFM+行为数据的算法实现
  • 终极指南:WaveTools鸣潮工具箱的完整使用教程与抽卡记录分析
  • 无锡哪家羽毛球馆高手多
  • 企业落地 AI Agent Harness Engineering 的第一个坑:说人话的需求与机器的工作流
  • cursor如何打开一个remote ssh
  • 2026反向海淘业务复盘:垂直品类选品+代购系统架构落地+类目优化技术
  • 微生物菌种采购新趋势:如何科学选择优质供应商
  • 工业遗留系统维护:从qmp32.dll缺失看DLL依赖与安全获取方案
  • Kodiak如何借助AI与概率风险评估保障自动驾驶卡车安全
  • 2026年天津地道天津菜推荐榜单:5家老字号津菜馆本地人吃了都说好 - 本地品牌推荐