标签:直接 组合 方向 target space max 告诉 print clu
通过这个题理解了一下反链的概念,更新在图论知识点里了
每个点向右和下连边可以建出一张图,这个题事实上是让我们求图的最小链覆盖。Dilworth定理告诉我们,最小链覆盖等于最长反链(反链:DAG中的一个点集,其中的点两两不可达),所以我们在横/纵一个方向上反着做dp即可(另一个方向正着,这里以从下往上,从左往右为例),每次从左,下和左下转移来。
只在从左下转移来有一个$a[i][j]$的贡献,为什么?
因为只有这时两个点互相不可达,符合反链的条件(可以看出这样的一对角线上的点都是满足这个条件的)。这也是为什么我们只在一个方向上反着做,因为两个方向都反着做那不叫求最长反链,那是建了一张反图,本质上和直接正着做是一样的=。=
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N=2005; 6 int mapp[N][N],dp[N][N]; 7 int T,n,m; 8 int main () 9 { 10 scanf("%d",&T); 11 while(T--) 12 { 13 memset(dp,0,sizeof dp); 14 scanf("%d%d",&n,&m); 15 for(int i=1;i<=n;i++) 16 for(int j=1;j<=m;j++) 17 scanf("%d",&mapp[i][j]); 18 for(int i=n;i;i--) 19 for(int j=1;j<=m;j++) 20 dp[i][j]=max(dp[i+1][j-1]+mapp[i][j],max(dp[i+1][j],dp[i][j-1])); 21 printf("%d\n",dp[1][m]); 22 } 23 return 0; 24 }
标签:直接 组合 方向 target space max 告诉 print clu
原文地址:https://www.cnblogs.com/ydnhaha/p/9757974.html