洛谷 P1107 BJWC2008 雷濤的小貓

2021-09-02 02:22:57 字數 1803 閱讀 4564

傳送門

這道題其實是道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高度上有多少個柿子):

1. f[

i][j

]=f[

i+1]

[j]+

a[j]

[i

]1.f[i][j]=f[i+1][j]+a[j][i]

1.f[i]

[j]=

f[i+

1][j

]+a[

j][i

]即直接向下跳的方案

2. f[

i][j

]=ma

x2.f[i][j]=max\

2.f[i]

[j]=

max即從任意一棵樹上跳到第j

jj棵上

但這時,我們發現,對於第二個方程的總時間複雜度是o(n

2h

)o(n^2h)

o(n2h)

,而這個資料量對於n,h

<

=2000

n,h<=2000

n,h<=2

000是行不通的

故我們需要對第二個方程進行優化。首先我們想到i−d

i-di−

d是個定值,而在此高度上的最大柿子收益我們在之前也已經算出來了,我們可以設g[i

]g[i]

g[i]

為第i

ii高度上的柿子最大收益

這樣第二個方程的時間複雜度就變成了高效的o(n

h)

o(nh)

o(nh)

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define ll long long

using namespace std;

inline ll read()

while

(s>=

'0'&&s<=

'9')

return d*f;

}int f[

2005][

2005

],g[

2005

],a[

2005][

2005];

intmax

(int x,

int y)

intmain()

}for

(int i=h;i;i--

)for

(int j=

1;j<=n;j++

) g[i]

=max

(f[i]

[j],g[i]);

} cout<;return0;

}

洛谷 P1107 BJWC2008 雷濤的小貓

給出若干棵樹,以及每棵樹不同高度有幾個柿子的資訊。以及給出走法規則,求能夠獲取到最多的柿子數。我自己的方法是 設dp i j 表示第j棵樹,高度為i時獲得的最大值。然後三重迴圈遍歷一下,第三重迴圈的含義是從之前較高的樹上找出乙個最大的值 乙個最優解 如下 dp計算 for int i h delta...

洛谷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...