首页 > 代码库 > BZOJ 3997 [TJOI2015]组合数学(单调DP)

BZOJ 3997 [TJOI2015]组合数学(单调DP)

 

【题目链接】 http://www.lydsy.com/JudgeOnline/problem.php?id=3997

 

【题目大意】

  给出一个网格图,其中某些格子有财宝,每次从左上角出发,只能向下或右走。
  问至少走多少次才能将财宝捡完。此对此问题变形,假设每个格子中有好多财宝,
  而每一次经过一个格子至多只能捡走一块财宝,至少走多少次才能把财宝全部捡完。

 

【题解】

  最小链覆盖=最长反链,反链的意思就是该集合中的点相互之间不互达,
  在该题中,最长反链可以用dp得出。

 

【代码】

#include <cstdio>#include <algorithm>using namespace std;const int N=1010;int T,n,m,a[N][N];long long dp[N][N];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",&a[i][j]);        for(int i=1;i<=n;i++){            for(int j=m;j;j--)dp[i][j]=max(dp[i-1][j+1]+a[i][j],max(dp[i-1][j],dp[i][j+1]));        }printf("%lld\n",dp[n][1]);    }return 0;}

BZOJ 3997 [TJOI2015]组合数学(单调DP)