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

洛谷 P6715 [CCO 2018] Fun Palace (神秘DP)

模拟赛的神题。想了 4h 没有拼出任意一个多项式做法。

在赛后被同学指点了一下发现状态要这么设——设 \(f_{i,j}\) 表示考虑前 \(i\) 个房间,第 \(i\) 个房间所有时间内最大有 \(j\) 个人的情况下的最大总人数。

至于为什么要这么设,我自己分析了一下感觉是因为每个房间的人数最大值其实才是会影响能不能打开其他的门的因素,而不是某一时间内有多少人。因为人可以流动,而且我们只通过最大人数就可以确定每扇门能不能开。

具体来说,分类讨论一下:

  1. 如果 \(j<a_i\),要么 \(i\)\(i+1\) 永远也连不上,此时 \(f_{i,j}+k\to f_{i+1,k}(k<b_i)\)。要么 \(i+1\) 可以把门打开来到 \(i\),此时我们 \(j\) 个人都应该是从 \(i+1\) 过来的,否则的话就与我们最大人数为 \(j\) 矛盾了(因为 \(i+1\) 能不能到 \(i\) 和当前 \(j\) 无关),此时 \(f_{i,j}+b_i\to f_{i+1,j+b_i}\)

  2. 如果 \(a_i \le j < a_i+b_i\),代表 \(i\)(一部分) 人能到 \(i+1\),具体来说是 \(j - a_i\) 人能到 \(i+1\),因为还要留 \(a_i\) 个人开门。此时 \(i+1\) 的房间的所有人都应该是从 \(i\) 来的,不然 \(i+1\) 的人就能到 \(i\),最大人数就不是 \(j\) 了。所以此时 \(f_{i,j} \to f_{i+1,j-a_i}\),注意这一过程没有产生任何新人。

  3. 如果 \(j\ge a_i+b_i\),则我们可以这么想:先用 \(a_i\) 个人开门,至少 \(b_i\) 个人过去 \(i+1\),再用这 \(b_i\) 个人开门,剩下的人走到 \(i+1\)。这样相当于是,所有的 \(j\) 个人都可以自由在 \(i\)\(i+1\) 之间来回走,所以是 \(f_{i,j}\to f_{i+1,j}\)。注意这一过程也没有任何的新人。

于是这个转移就做完了。这个状态设计和分讨的转移感觉都特别高手,同时也很神秘。首先这样转移答案一定不会更多是肯定的,因为我们可以从转移的路径还原回一个合法的方案。但是为什么这样一定能覆盖到最优解呢?一个感性的理解是,我们的状态其实能覆盖到所有的合法方案,所以一定不会漏掉解法。同时由于我们的转移也能与方案的决策一一对应,所以解法一定是最优的。

最后的时间复杂度 \(O(nV)\)

const int MAXN = 1e3 + 5, MAXM = 2e4 + 5;
int n, m, a[MAXN], b[MAXN], f[MAXN][MAXM], tmp[MAXN];void chkmx(int &x, int y) {x = max(x, y);
}void work() {cin >> n >> m;int M = m;for (int i = 1; i < n; ++i) {cin >> a[i] >> b[i];M = max(a[i] + b[i], M);}for (int j = 1; j < m; ++j)f[1][j] = j;for (int i = 1; i < n; ++i) {for (int j = 0; j <= M; ++j) {if (i != 1 && j < b[i - 1]) {chkmx(f[i][j], tmp[i - 1] + j);}if (j < a[i]) {if (j + b[i] <= M) chkmx(f[i + 1][j + b[i]], f[i][j] + b[i]);chkmx(tmp[i], f[i][j]);} else if (j < a[i] + b[i]) {chkmx(f[i + 1][j - a[i]], f[i][j]);} else {chkmx(f[i + 1][j], f[i][j]);}}}for (int j = 1; j < b[n - 1]; ++j) {chkmx(f[n][j], tmp[n - 1] + j);}int ans = *max_element(f[n] + 1, f[n] + 1 + M);cout << ans << endl;
}
http://www.hskmm.com/?act=detail&tid=32692

相关文章:

  • AT 随机做题 I
  • moni 32
  • git 舍弃当前所有修改
  • 2025.10.17——1蓝
  • C# 使用 using 关键字间接实现只读局部变量的方法
  • 画图3D真好用 - Gon
  • 高校与某中心共建机器人技术教育项目
  • 2025年国际物流服务领域优质品牌最新推荐排行榜 —— 聚焦行业头部企业核心优势与选择参考
  • WordPress维护模式完整指南:手动实现与插件方案
  • Lean语言如何连接数学与编程
  • Github上文本切分相关的优秀项目
  • 微信机器人开发
  • 微信社群机器人开发
  • 《程序员修炼之道:从小工到专家》第三章读后感
  • 原型链污染学习
  • 重新认识 Golang 中的 json 编解码
  • (二)CUDA在Windows系统上的编译运行方法
  • 关于价值原语与AI元人文构想的对话全记录——DeepSeek研究
  • 关于价值原语与AI元人文构想的对话全记录
  • 升鲜宝生鲜配送供应链管理系统,辅助开发工具,《多语言自动翻译与导出工具(WinForms版)》开发文档 及 阿里云机器翻译,数据库Mysql .net 全部源代码
  • MySQL学习
  • 植物大战僵尸全系列下载 PVZ植物大战僵尸全集版分享下载 原版民间修改版含安卓手机+电脑+ios各平台
  • 10.17
  • Pytorch66页实验题
  • Excel学习
  • 记一次激活Jetbrains全家桶流程
  • uni-app x开发商城系统,商品列表
  • PySimpleGUI 中有没有类似VB的timer组件
  • 【填坑】电脑用户名有中文字符,如何与github建立SSH连接
  • 数据采集第一次作业