洛谷 P1133 教主的花園 題解

2021-08-27 16:14:31 字數 1435 閱讀 3875

通往題目的大門

進入正題,需要求最大觀賞價值,那麼用於dp的f陣列首先肯定要有兩維,第一維i表示第i個位置,第二維j表示種第j種樹(我們不妨設10,20,30這三種樹為1,2,3),然後又發現,第i個位置能種什麼樹,不單單跟上乙個位置有關,還跟上上個位置有關,那這樣呼叫兩位去dp顯得十分複雜,於是我們再開一維,表示這個位置的樹比上乙個位置的樹要高還是要低(0表示低,1表示高),於是,我們就可以寫出dp方程:

f[i][1][0]=maxx(f[i-1][2][1],f[i-1][3][1])+a[i].x;//第i個位置種第1種樹,那麼它肯定比上一棵樹要矮,所以第3維是0,於是看上一棵樹(第i-1棵)是2還是3,因為第i-1棵比第i棵樹要高,那麼他一定也比第i-2棵樹要高,所以他們的第3維都是1,記得後面還要加上當前這棵樹的貢獻

f[i][2][0]=f[i-1][3][1]+a[i].y;//如果種2並且小於前一種,那前一種只能種3

f[i][2][1]=f[i-1][1][0]+a[i].y;//下面這兩行類似

f[i][3][1]=maxx(f[i-1][1][0],f[i-1][2][0])+a[i].z;

做完了?不存在的。(告訴你們個大冪冪這個做法在洛谷上70分)

仔細想想,發現這個做法只能滿足線型地種樹,也就是一排種過去,但是,題目要求是環形,也就是說,我們需要處理頭和尾的問題,所以,我們再加一維,表示第乙個位置種的是什麼樹。

可以發現,第3~n-1個位置種什麼樹跟第乙個位置種什麼樹然而並沒有什麼關係,只要保證他們第四維相等就可以照常轉移了,於是我們稍稍修改一下上面的**,加上第四維,就得出這樣乙個東西:

for(int j=1;j<=3;j++)

**的核心部分就是這樣了,然後再初始化一下第一位

初始化第乙個位置:

f[1][1][0][1]=a[1].x;//注意第2維一定和第4維是一樣的,這段初始化也沒啥不好理解的,注釋就不打啦

f[1][2][0][2]=a[1].y;

f[1][2][1][2]=a[1].y;

f[1][3][1][3]=a[1].z;

總體**:

#include #include int f[100010][4][2][4];

struct node;

node a[100010];

int n;

inline int maxx(int x,int y)

int main()

} printf("%d",maxx(maxx(maxx(maxx(maxx(f[n][1][0][2],f[n][1][0][3]),f[n][2][0][3]),f[n][2][1][1]),f[n][3][1][1]),f[n][3][1][2]));//最後從所有可能的情況中選擇最大值輸出

}

洛谷 題解 P1133 教主的花園

n 10 5 o n 演算法 dp i j k 表示在第i個位置,種j 10的高度的樹,且這棵樹是否比相鄰兩棵樹高dp i 1 0 max dp i 1 2 1 dp i 1 3 1 a i 種高度為10的樹,肯定比相鄰的兩棵樹矮 dp i 2 0 dp i 1 3 1 b i 種高度為20且高度比...

洛谷 P1133 教主的花園

教主有著乙個環形的花園,他想在花園周圍均勻地種上n棵樹,但是教主花園的土壤很特別,每個位置適合種的樹都不一樣,一些樹可能會因為不適合這個位置的土壤而損失觀賞價值。教主最喜歡3種樹,這3種樹的高度分別為10,20,30。教主希望這一圈樹種得有層次感,所以任何乙個位置的樹要比它相鄰的兩棵樹的高度都高或者...

dp 洛谷P1133 教主的花園

一開始題目看錯了,以為很水的 然後0 爆蛋之後開始想標算 想了半天就是不知道怎麼處理這個環 設f i j k 表示第i行第j列的答案 k 0表示前面比他小 k 1表示前面比他大 但是這樣我們第一位要靠第n位來更新 那我們直接不更新第一位 從第二位來,然後跑完後把n位和1位結合一下就好了 includ...