P3974 TJOI2015 組合數學

2022-03-23 03:04:09 字數 1778 閱讀 6669

為了提高智商,zjy開始學習組合數學。某一天她解決了這樣乙個問題:給乙個網格圖,其中某些格仔有財寶。每次從左上角出發,只能往右或下走。問至少要走幾次才可能把財寶全撿完。

但是她還不知足,想到了這個問題的乙個變形:假設每個格仔中有好多塊財寶,而每一次經過乙個格仔至多只能撿走一塊財寶,其他條件不變,至少要走幾次才可能把財寶全撿完?

這次她不會做了,你能幫幫她嗎?

輸入格式:

第一行為乙個正整數t,表示資料組數

每組資料的第一行是兩個正整數n和m,表示這個網格圖有n行m列。

接下來n行,每行m個非負整數,表示這個格仔中的財寶數量(0表示沒有財寶)。

輸出格式:

對於每組資料,輸出乙個整數,表示至少走的次數。

輸入樣例#1: 

1

3 30 1 5

5 0 0

1 0 0

輸出樣例#1: 

10
對於30%的資料,n≤5.m≤5,每個格仔中的財寶數不超過5塊。

對於50%的資料,n≤100,m≤100,每個格仔中的財寶數不超過1000塊

對於100%的資料,n≤1000,m≤1000,每個格仔中的財寶不超過10^6塊

這是天津市2023年的省選題(天津好像離北京很近~~~)於是乎我就做了這道題。。。

題目的意思就是用最少的鏈覆蓋住整個圖,自然而然(看過題解後)就想到了最小鏈覆蓋;

而根據著名的(反正我是沒聽過)的dilworth定理,dag最小鏈覆蓋的條數就等於最大點獨立集/最長反鏈的元素個數;;;

所謂de反鏈就是去找一些點,其中找兩個點,使其直接間接均不可達;而反鏈中元素最多的就是最長反鏈了。

所以這個題的本質上是去找這個圖的最長反鏈。

接下來就到了我們有趣的dynamic programming環節辣;;;

由題目可知,只能從左往右,從上往下走,所以這個題的反鏈一定是由右上到左下的。

而從上面和右面均能形成鏈,所以直接它直接就可能是這個點的最長反鏈;

從右上走到左下是不可能的,所以我們要把右上的點加上這個點的值才可能是最長反鏈;

而我們要求的是最長反鏈,但這幾個部分顯然是不能夠同時取的,所以要選這三個的最大值

狀態轉移方程就很容易寫出了:

1 f[i][j]=max(f[i-1][j+1]+a[i][j],max(f[i-1][j],f[i][j+1]));
view code

這裡還要注意的一點就是迴圈變數,i是從1-〉n遞增的,j是從m-〉1遞減的,原因很簡單,就是要滿足最長反鏈從左下不可能到達右上的性質;

1 #include2 #include//

getchar要引cstdio

3using

namespace

std;

4int

t,n,m;

5long

long a[1005][1005],f[1005][1005];//

要開大!洛谷上本題有5個極限資料,不開就會re得很慘~

6int read()//

讀入優化711

while(s>='

0'&&s<='9')

12return x*f;13}

14int

main()

1528}29

//dp

30for(int i=1;i<=n;i++)

3136

}37 cout<1]/

千萬不要忘記輸出回車。。。我爆了5次零。。。38}

39 }

view code

洛谷P3974 TJOI2015 組合數學

dilworth定理,把每個位置的每個寶物當做乙個點,可以互相到達的寶物當成鏈,那麼不可互相到達的也就是每個位置的左下角和右上角,就是反鏈,這題就最少鏈覆蓋,也就是求最長反鏈大小,而同乙個位置的不同寶物不能互相到達。這樣直接從左下dp到右上就行了。includeusing namespace std...

洛谷P3974 TJOI2015 組合數學

為了提高智商,zjy開始學習組合數學。某一天她解決了這樣乙個問題 給乙個網格圖,其中某些格仔有財寶。每次從左上角出發,只能往右或下走。問至少要走幾次才可能把財寶全撿完。但是她還不知足,想到了這個問題的乙個變形 假設每個格仔中有好多塊財寶,而每一次經過乙個格仔至多只能撿走一塊財寶,其他條件不變,至少要...

TJOI2015 組合數學

這個東西一看就是二維偏序嗎?首先考慮把乙個權值為v的點拆成v的相同的點,這v個點相互不可比的。這樣答案變成了最小鏈覆蓋。dilworth定理 最小鏈覆蓋 最大反鏈。乙個點拆成了v的點,因為這v個點互不可比,那這v個點肯定要同時選,所以其實相當求點權和最大的反鏈,這個寫個sb動態規劃就行了。code ...