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

Dilworth定理及其在算法题中的应用

1. Dilworth定理

Dilworth定理由数学家Robert P. Dilworth于1950年提出,它描述了偏序集中链和反链之间的关系。

  • 偏序集:一个集合 equipped with a partial order(即一个自反、反对称、传递的关系)。
  • :偏序集的一个子集,其中任意两个元素都是可比较的(即全序子集)。
  • 反链:偏序集的一个子集,其中任意两个元素都是不可比较的。

Dilworth定理:在任意有限偏序集中,其最小链划分的大小(即将偏序集分解成链的最小数量)等于其最大反链的大小(即反链中元素的最大数量)。

例子:考虑一个序列 [3, 1, 2],其中偏序关系基于元素值和位置(例如,元素值越小越“小”,但位置也影响)。Dilworth定理可以帮助我们找到最小链分解。

2. 序列分解定理

序列分解定理是Dilworth定理在序列上的一个特例。它关注的是序列能否被分解为k个非递减子序列。

  • 非递减子序列:一个子序列其中每个元素都不小于前一个元素(即单调非递减)。
  • 分解:将原序列的每个元素分配到k个子序列中,使得每个子序列都是非递减的。

序列分解定理:一个序列可以被分解为k个非递减子序列 当且仅当 序列中最长递减子序列的长度不超过k。

这意味着:

  • 如果序列中存在一个长度为k+1的递减子序列,那么它无法被分解成k个非递减子序列。
  • 反之,如果最长递减子序列的长度为k,那么序列可以被分解成k个非递减子序列。

Dilworth定理为这个结论提供了严格的数学基础:在序列构成的偏序集(基于值和位置)中,反链对应递减子序列,链对应非递减子序列。

3. 定理在算法题中的应用 (CF-2143-D1)

题目链接:[[https://codeforces.com/contest/2143/problem/D1]]
这个题需要统计所有“好”子序列(即可以被分解为两个非递减子序列的子序列)。根据序列分解定理,这等价于统计所有最长递减子序列长度不超过2的子序列。这可以用dp快速解决:记dp[i][j](其中 ij 表示两个非递减链的最后一个元素值,且 i<=j)为子序列的数量。对于每个新元素 v,我们检查是否能将其添加到第一个链(如果 v>=i)或第二个链(如果 v>=j),并更新状态,最后统计即可。

直观上,如果序列中有三个元素递减(如 a > b > c 且顺序出现),那么这三个元素无法被分配到两个非递减链中(因为每个链必须非递减,但递减关系要求它们分属不同链,但只有两个链,矛盾)。反之,如果没有这样的三个元素,那么总可以通过贪心将序列分解为两个非递减链。

AC代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod = 1e9+7;signed main(){ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);auto solve = [&](){int n;cin >> n;vector<int> a(n);for (int i=0; i<n; i++) cin >> a[i];vector<vector<int>> dp(n+1, vector<int>(n+1, 0));dp[0][0] = 1;  // 空序列for (auto v: a){vector<vector<int>> cpydp = dp;for(int i=0; i<=n; i++){for(int j=0; j<=n; j++){if(dp[i][j] == 0) continue;if(v >= i)cpydp[v][j] = (cpydp[v][j]+dp[i][j])%mod;else if(v >= j)cpydp[i][v] = (cpydp[i][v]+dp[i][j])%mod;}}dp = cpydp;}int ans = 0;for(int i=0; i<=n; i++)for(int j=0; j<=n; j++)ans = (ans+dp[i][j])%mod;cout << ans << "\n";};int T;for(cin>>T; T--; ) solve();return 0;
}
http://www.gsyq.cn/news/8147.html

相关文章:

  • AI一周资讯 250913-250919
  • QMT交易系统向服务器同步订单丢失问题排查
  • 笔记1
  • 实用指南:OSPF特殊区域、路由汇总及其他特性
  • 实用指南:Ubuntu22.04安装配置typora
  • python 读取大文档优化示例
  • HR 需了解的绩效评估应包含的内容
  • 解题报告-P12022 [USACO25OPEN] Hoof Paper Scissors Minus One B
  • CentOS架构修改网卡命名的方法总结
  • 主流的开源协议(MIT,Apache,GPL v2/v3) - 实践
  • 解题报告-P12025 [USACO25OPEN] Sequence Construction S
  • 解题报告-P12026 [USACO25OPEN] Compatible Pairs S
  • ctfshow web52
  • S32K3便捷的平台eMIOS 应用说明
  • Ubuntu 18.04 LTS 安装 6.10.10 内核 - 教程
  • ctfshow web39
  • 国标GB28181视频平台EasyGBS核心功能解密:如何实现海量设备的录像精准检索与高效回放?
  • 行程长度编码
  • mysql 虚拟列,可以简化 SQL 逻辑、提升查询效率
  • 多站点的TSP问题求解-06 - jack
  • C# CAN通信上位机系统设计与实现
  • 进程池VS线程池
  • python+Django开发笔记(结合禅道开发测试报告)
  • Questions about learning Symfony
  • ctfshow web22(子域名爆破)
  • PLC中的运动控制 - (一)轴
  • ctfshow web23(代码审计编写脚本爆破)
  • 完整教程:ARM指令集总结
  • 封神台 第二章:遇到阻难!绕过WAF过滤
  • uniGUI:在Linux上部署独立应用为服务