標籤:直接 組合 方向 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 組合數學