定理1 令X是一个有限偏序集,并令r是其最大链的大小。则X可以被划分成r个但不能再少的反链。 其对偶定理称为Dilworth定理:
定理2 令X是一个有限偏序集,并令m是反链的最大的大小。则X可以被划分成m个但不能再少的链。
证明:
设p为最少反链个数
(1)先证明X不能划分成小于r个反链。由于r是最大链C的大小,C中任两个元素都可比,因此C中任两个元素都不能属于同一反链。所以p>=r。
(2)设X1=X,A1是X1中的极小元的集合。从X1中删除A1得到X2。注意到对于X2中任意元素a2,必存在X1中的元素a1,使得a1<=a2。令A2是X2中极小元的集合,从X2中删除A2得到X3……最终,会有一个Xk非空而X(k+1)为空。于是A1,A2,...,Ak就是X的反链的划分,同时存在链a1<=a2<=...<=ak,其中ai在Ai内。由于r是最长链大小,因此r>=k。由于X被划分成了k个反链,因此r>=k>=p。因此r=p,定理1得证。
扩展到这题,是个DAG,那么这题的最小链覆盖数就是最大点独立集(链可以交)
对于这题网格图 对于点(i,j),与其有偏序关系的是(i-1,j)//向下走,(i,j+1)//向右走,与其没有偏序关系的就是(i-1,j+1)
这样的关系也可以递推,从而知道对于一个格子位置,和它有偏序关系的一定是行列均大于它或均小于它的格子;无偏序关系的一定是行列一个大于它一个小于它或相反的格子。
最后在反链上跑最长路即可
const int N=1007;
int n,m;
int a[N][N];
lxl f[N][N];
int main() {
int T;
read(T);
while(T--){
read(n);read(m);
memset(f,0,sizeof f);
memset(a,0,sizeof a);
rep(i,1,n){
rep(j,1,m){
read(a[i][j]);
}
}
rep(i,1,n){
drp(j,m,1){
f[i][j]=max(f[i-1][j+1]+a[i][j],max(f[i-1][j],f[i][j+1]));//前一个是(i,j)本身的反链长,后两个是可以继承的反链长度
}
}
out(f[n][1],'
');
}
return 0;
}