BZOJ 3997 TJOI2015 组合数学 Dilworth定理

题目大意:给定一个网格图,每次从左上角出发,只能往右或往下走,最后到达右下角,每个格子有最低经过次数,问最少走几次
Dilworth定理:DAG的最小链覆盖=最大点独立集
最小链覆盖指选出最少的链(可以重复)使得每个点都在至少一条链中
最大点独立集指最大的集合使集合中任意两点不可达
此题中最大点独立集显然是一个集合满足集合中任意两点都是左下-右上的关系
DP一遍就能出解 复杂度 O(Tmn)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 1010
using namespace std;
int m,n;
long long ans;
int a[M][M];
long long f[M][M];
int main()
{
    int T,i,j;
    for(cin>>T;T;T--)
    {
        cin>>m>>n;ans=0;
        for(i=1;i<=m;i++)
            for(j=1;j<=n;j++)
                scanf("%d",&a[i][j]);
        memset(f,0,sizeof f);
        for(j=1;j<=n;j++)
        {
            for(i=m;i;i--)
                f[i][j]=max(f[i][j-1],f[i+1][j-1]+a[i][j]);
            for(i=m;i;i--)
                f[i][j]=max(f[i][j],f[i+1][j]);
            ans=max(ans,f[1][j]);
        }
        cout<<ans<<endl;
    }
    return 0;
}

你可能感兴趣的:(动态规划,bzoj,BZOJ3997,Dilworth定理)