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

P6715 [CCO 2018] Fun Palace 题解

Description

有一个含 \(n\) 个点的链,每个点有一个权值。

对于任何 \(1\le i\le n-1\),都有一条边连接 \((i,i+1)\)

您可以在链中的任意一些节点放置一些生物。

对于第 \(i\) 条边,若点 \(i\) 至少有 \(a_i\) 个生物或点 \(i+1\) 至少有 \(b_i\) 生物,则该边可以打开。

链是有出口的,如果在 \(1\) 号点有 \(m\) 个生物,则出口会被打开。

您要确定,至多放置多少个生物,可以使得生物不会打开出口。

打开了不一定能走过去。

\(1\le n\le 10^3\)\(1\le m,a_i,b_i\le 10^4\)

Solution

先考虑已知初始每个节点上的生物数量,对于每个位置如何最大化其上面的生物数量。

注意到操作可逆,所以可以先让对于每个节点从左往右,去让其上的生物尽可能多的往右走。再从右往左让生物尽可能往左走,这么一直先右后左地走很多轮,最后一次往左时走到 \(i\) 号点时 \(i\) 上的生物数量就是这个位置可能的最大生物数量。

由于限制条件是终止状态下 \(1\) 号点上的生物数量,所以如果直接对初始状态每个点上的生物数量做的话会很难刻画最终状态。又因为最终状态下再做一次先右后左后整个状态不会变,所以考虑直接对最终状态 dp。

\(c_i\) 表示最终状态下第 \(i\) 个点的生物数量,即做很多次先右后左后的结果,\(s_i\) 表示第 \(i\) 个点可能的最大生物数量,注意 \(c_i\) 不等于 \(s_i\)

显然 \(c_1=s_1\)。同时对于每个 \(i(i>1)\),向右第一次推到 \(i\) 和向左第一次推到 \(i\)\(i\) 上的数量为 \(s_i\),向右到 \(i+1\) 以及向左到 \(i-1\)\(i\) 上的数量为 \(c_i\)。然后进行分讨:

  1. \(s_i\geq a_i+b_i\)

    向右从 \(i\) 推到 \(i+1\)\(i\) 上的 \(s_i\) 个生物显然能够全部到 \(i+1\),所以 \(s_{i+1}\geq s_i\)。向左从 \(i+1\) 推到 \(i\)\(i+1\) 上的 \(s_{i+1}\) 个生物同样能够全都回 \(i\),所以 \(s_{i}\geq s_{i+1}\)

    由于 \(i\) 推到 \(i+1\) 时如果 \(c_{i+1}\neq 0\),就会得到 \(s_{i+1}\geq c_{i+1}+s_i>s_i\),矛盾。所以 \(c_{i+1}=0\)

  2. \(a_i\leq s_i<a_i+b_i\)

    向右从 \(i\) 推到 \(i+1\)\(i\) 会剩下 \(a_i\),而 \(i+1\) 会变为 \(c_{i+1}+s_i-a_i\),所以 \(s_{i+1}\geq c_{i+1}+s_i-a_i\)。再从 \(i+1\) 推回 \(i\) 时,\(i\) 能够将 \(i+1\) 上的生物全吸过去,所以 \(s_i\geq a_i+s_{i+1}\geq c_{i+1}+s_i\)

    容易得到 \(c_{i+1}=0,s_{i+1}=s_i-a_i\)

  3. \(0\leq s_i<a_i\)

    这个时候就要讨论 \(i+1\) 能否推回 \(i\) 了。

    1. \(s_{i+1}\geq b_i\)

      如果 \(s_{i+1}\geq a_i+b_i\)\(s_i\) 就必须等于 \(s_{i+1}\),与 \(s_i<a_i\) 矛盾,所以 \(s_{i+1}<a_i+b_i\)

      显然 \(i\) 推不到 \(i+1\)。从 \(i+1\) 推回 \(i\) \(i\) 上只能剩下 \(0\) 个生物,否则 \(i+1\) 会吸过去让 \(s_{i+1}\) 更大。从 \(i+1\) 推回 \(i\) \(i+1\) 会剩下 \(b_i\)\(i\) 会得到 \(s_{i+1}-b_i\)

      所以 \(c_{i+1}=b_i,s_{i+1}=s_{i}+b_i\)

    2. \(0\leq s_{i+1}<b_i\)

      \(i\)\(i+1\) 无法互通,所以只需要满足 \(s_{i+1}=c_{i+1}\)

考虑根据上面的东西进行 dp,设 \(f_{i,j}\) 表示考虑了 \([1,i]\)\(s\)\(c\),钦定 \(s_i=j\)\(\max_{j=1}^{i}c_j\) 的最大值,初始状态是 \(f_{1,j}=j(0\leq j<m)\),可以得到转移:

\[\begin{cases} f_{i+1,j}\leftarrow f_{i,j}&(j\geq a_i+b_j)\\ f_{i+1,j-a_i}\leftarrow f_{i,j}&(a_i\leq j<a_i+b_i)\\ f_{i+1,j+b_i}\leftarrow f_{i,j}+b_i&(0\leq j<a_i)\\ f_{i+1,k}\leftarrow f_{i,j}+k&(0\leq j<a_i,0\leq k<b_i) \end{cases} \]

直接转移即可,最终结果是 \(f_{n,*}\) 的最大值。

时间复杂度:\(O(nV)\)

Code

#include <bits/stdc++.h>// #define int int64_tconst int kMaxN = 2e3 + 5, kMaxM = 4e4 + 5;int cid, n, m, lim;
int a[kMaxN], b[kMaxN], f[2][kMaxM];inline void chkmax(int &x, int y) { x = (x > y ? x : y); }
inline void chkmin(int &x, int y) { x = (x < y ? x : y); }void dickdreamer() {std::cin >> n >> m;lim = m;for (int i = 1; i < n; ++i) std::cin >> a[i] >> b[i], lim = std::max({lim, a[i], b[i]});lim *= 2;int o = 0;std::fill_n(f[o], lim + 1, -1e9);for (int i = 0; i < m; ++i) f[o][i] = i;for (int i = 1; i < n; ++i) {o ^= 1;std::fill_n(f[o], lim + 1, -1e9);int mx = -1e9;for (int j = 0; j <= lim; ++j) {if (j >= a[i] + b[i]) {chkmax(f[o][j], f[o ^ 1][j]);} else if (j >= a[i]) {chkmax(f[o][j - a[i]], f[o ^ 1][j]);} else {chkmax(f[o][j + b[i]], f[o ^ 1][j] + b[i]);chkmax(mx, f[o ^ 1][j]);}}for (int j = 0; j < b[i]; ++j) chkmax(f[o][j], mx + j);}int ans = -1e9;for (int i = 0; i <= lim; ++i) chkmax(ans, f[o][i]);std::cout << ans << '\n';
}int32_t main() {
#ifdef ORZXKRfreopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout);
#endifstd::ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0);int T = 1;std::cin >> cid >> T;while (T--) dickdreamer();// std::cerr << 1.0 * clock() / CLOCKS_PER_SEC << "s\n";return 0;
}
http://www.hskmm.com/?act=detail&tid=33848

相关文章:

  • WebGL学习及项目实战(第03期:绘制多个点,线,面)
  • CF 359D. Pair of Numbers
  • 2025多校CSP模拟赛6
  • Java基础——类型转换,变量、常亮、作用域,基本运算符
  • 洛谷 LGR-246 S 模拟赛
  • godot3D节点本身的偏转数值错误竟会导致空间移动穿模??!
  • 题解:qoj7938 Graph Race
  • java中的初等函数
  • 分治算法
  • 专用硬件神经网络优化技术解析
  • 学习逆向的背景知识(自用)
  • Linux-网络安全私房菜(二)
  • pycharm使用远程的ssh的解释器
  • Android SSL Pinning检测利器:SSLPinDetect技术解析
  • AI元人文:社区调解的数字剧场
  • 2025年粉末冶金制品/零件厂家推荐排行榜,专业制造与高品质服务的首选!
  • Dubbo入门-Dubbo的快速使用
  • 站位2
  • 傅里叶变换及DCT点滴
  • 【未完待续】MkDocs 部署安装教程
  • 傅里叶变换点滴
  • [PaperReading] SAIL-Embedding Technical Report: Omni-modal Embedding Foundation Model
  • 人生四大支柱 - 健康,金钱,工作,关系
  • 英伟达个人AI超算Spark技术解析
  • [buuctf]jarvisoj_level3_x64
  • SpringBoot系列十三:SpringBoot面试常见问题
  • [LangChain] 04. 提示词模板
  • 2025 最新不锈钢板厂家推荐榜:剖析国内头部品牌竞争优势,附优质供应商选择指南N06625/N06600/C70600不锈钢板厂家推荐
  • 2025 夹丝玻璃源头厂家最新推荐排行榜:解析防火 / 艺术 / 酒店等多场景厂商优势,助力精准选型
  • 2025 中空板源头厂家最新推荐排行榜揭晓:覆盖全产业链,老牌与新锐共筑品质标杆