码迷,mamicode.com
首页 > 其他好文 > 详细

解题:TJOI 2015 组合数学

时间:2018-10-09 00:47:33      阅读:201      评论:0      收藏:0      [点我收藏+]

标签:直接   组合   方向   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 }
View Code

 

解题:TJOI 2015 组合数学

标签:直接   组合   方向   target   space   max   告诉   print   clu   

原文地址:https://www.cnblogs.com/ydnhaha/p/9757974.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!