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; }
愿你出走半生,归来仍是少年