[BZOJ 3997] 组合数学

Link:

BZOJ 3997 传送门

Solution:

这题是一个比较明显的最小链覆盖,只不过还给每条链加上了权值

$Dilworth$定理:最小链覆盖数=最长反链长度

一般用$Dilworth$定理都是求最长反链,这题算是逆运用吧

发现能构成反链的两点一定是具有“左上、右下”的位置关系

于是我们从右上角$<1,m>$开始,$dp$到左下角$<n,1>$即可

Code:

//by NewErA
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

ll T,dp[1005][1005],dat[1005][1005],n,m;

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                scanf("%d",&dat[i][j]);
        for(int i=1;i<=n;i++)
            for(int j=m;j;j--)
                dp[i][j]=max(dp[i-1][j+1]+dat[i][j],max(dp[i-1][j],dp[i][j+1]));
        printf("%d\n",dp[n][1]);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/newera/p/9139024.html