傳送門
這道題其實是道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...