[TJOI2015]组合数学
有如下引理:
\(Dilworth\) 定理:最长反链=最小链覆盖=最大独立集
最小链覆盖:指选出最少的链(可以重复)使得每个点都在至少一条链中
最大独立集:指最大的集合使集合中任意两点不可达
我们考虑可达的点\((x_1,y_1),(x_2,y_2)\)满足偏序关系:\(x_1 \leq x_2,y_1 \leq y_2\)。
所以我们求最大独立集时,只要从右上转移即可,可以发现这样不重不漏。
#include<iostream>
#include<cstdio>
#define ll long long
#define N 1005
ll T;
ll f[N][N];
ll a[N][N];
ll n,m;
int main(){
scanf("%lld",&T);
while(T -- ){
scanf("%lld%lld",&n,&m);
for(int i = 1;i <= n;++i)
for(int j = 1;j <= m;++j)
scanf("%lld",&a[i][j]);
for(int i = 1;i <= n;++i)
for(int j = m;j >= 1;--j)
f[i][j] = std::max(f[i - 1][j],std::max(f[i][j + 1],a[i][j] + f[i - 1][j + 1]));
std::cout<<f[n][1]<<std::endl;
}
}