洛谷 P1107 BJWC2008 雷濤的小貓

2021-10-07 06:55:33 字數 1577 閱讀 6963

給出若干棵樹,以及每棵樹不同高度有幾個柿子的資訊。以及給出走法規則,求能夠獲取到最多的柿子數。

我自己的方法是:設dp[i][j]表示第j棵樹,高度為i時獲得的最大值。然後三重迴圈遍歷一下,第三重迴圈的含義是從之前較高的樹上找出乙個最大的值(乙個最優解)。**如下:

//dp計算

for(

int i = h-delta;i>

0;i--

) dp[i]

[j]+

= fruit[j]

[i];

//加上當前的果子

}}

但是這個**會讓你 tle,該如何簡化呢?可以看到這裡的最外層的for迴圈其實是高度從高到低,也就是說:較高層的最大值其實在除了第一次做j的迴圈時需要尋找,以後迴圈j的時候便不用再迴圈了,而是直接可以利用上一次找出的最大值,這個最大值放到rec中。rec[i]就表示高度為i時能夠得到最大值。修改後的**如下3示。

這是洛谷的大佬給出的想法:

將每棵樹的每個高度看成是乙個圖的節點,然後進行一波圖節點的轉移操作,最後得到乙個最優解。這裡的思想貴在抽象,能夠將所學的知識應用到實際的問題上!

// created by lawson on 20-6-17.

#include

#include

using namespace std;

const

int maxn =

2005

;int dp[maxn]

[maxn]

;//dp[i][j]表示第j棵樹,高度為i時獲得的最大值

int fruit[maxn]

[maxn]

;//fruit[i][j]表示第i棵樹,高度為j時有柿子

int rec[maxn]

;//rec[i]用於記錄高度為i時的最大值

int n,h,delta;

intmain()

}for

(int i = h;i>h-delta;i--)}

//dp計算

for(

int i = h-delta;i>

0;i--

)else

rec[i+delta]

= dp[i]

[j];

} dp[i]

[j]+

= fruit[j]

[i];

//加上當前的果子}}

int res =0;

for(

int i =

1;i<= n;i++

) res =

max(res,dp[1]

[i])

;printf

("%d\n"

,res)

;}

3 10 2

3 1 4 10

6 3 5 9 7 8 9

5 4 5 3 6 9

01.如何降維?

洛谷 P1107 BJWC2008 雷濤的小貓

傳送門 這道題其實是道dpdp dp題,但至於它為什麼會被分到數論,那就不得而知了.首先我們設f i j f i j f i j 為到第i ii高度在第j jj棵樹上時,我們可以摘到的最多柿子數,那麼這時我們可以得到兩個方程 a j i a j i a j i 表示第i ii棵樹的第j jj高度上有...

洛谷P1107 BJWC2008 雷濤的小貓

題目鏈結 n 2dp比較好想,f i j 表示第i棵樹高度為j的最大收益 直接從上到下轉移即可,每次記錄下max f 1 n j 用於下面的轉移 f i j max f i j 1 max f 1 n j delta max f 1 n j delta 是已經求出來的,o 1 查詢 列舉j和i,總複...

洛谷 P3197 HNOI2008 越獄

來來來,日常水一篇 滑稽 監獄有連續編號為1 n的n個房間,每個房間關押乙個犯人,有m種宗教,每個犯人可能信仰其中一種。如果相鄰房間的犯人的宗教相同,就可能發生越獄,求有多少種狀態可能發生越獄 輸入格式 輸入兩個整數m,n.1 m 10 8,1 n 10 12 輸出格式 可能越獄的狀態數,模1000...