1. 程式人生 > >洛谷教主花園dp

洛谷教主花園dp

using font www printf 約定 blog urn turn 序表

洛谷-教主的花園-動態規劃

題目描述

教主有著一個環形的花園,他想在花園周圍均勻地種上n棵樹,但是教主花園的土壤很特別,每個位置適合種的樹都不一樣,一些樹可能會因為不適合這個位置的土壤而損失觀賞價值。

教主最喜歡3種樹,這3種樹的高度分別為10,20,30。教主希望這一圈樹種得有層次感,所以任何一個位置的樹要比它相鄰的兩棵樹的高度都高或者都低,並且在此條件下,教主想要你設計出一套方案,使得觀賞價值之和最高。

輸入輸出格式

輸入格式:

輸入文件garden.in的第1行為一個正整數n,表示需要種的樹的棵樹。

接下來n行,每行3個不超過10000的正整數ai,bi,ci,按順時針順序表示了第i個位置種高度為10,20,30的樹能獲得的觀賞價值。

第i個位置的樹與第i+1個位置的樹相鄰,特別地,第1個位置的樹與第n個位置的樹相鄰。

輸出格式:

輸出文件garden.out僅包括一個正整數,為最大的觀賞價值和。

輸入輸出樣例

輸入樣例#1:
4 
1 3 2 
3 1 2 
3 1 2 
3 1 2
輸出樣例#1:
11

說明

【樣例說明】

第1~n個位置分別種上高度為20,10,30,10的樹,價值最高。

【數據規模與約定】

對於20%的數據,有n≤10;

對於40%的數據,有n≤100;

對於60%的數據,有n≤1000;

對於100%的數據,有4≤n≤100000,並保證n一定為偶數。

思路,這個題剛開始完全沒思路,後來參考某大佬題解。

本題妥妥的3維dp,我們不妨設dp[i][j][k],表示前i棵樹拜訪後得到的最大值,i表示第i棵樹,j表示這棵數高度為10還是20或是30,k表示這棵樹與他的前一棵樹的高度關系,1表示它比它前一棵樹矮,0表示它比它前一棵樹高,由於它是個環,所以我們可以用到一些方法,先考慮2~n的情況,再將n和1特判一下即可,

可能這個dp看起來有點“暴力”。

上代碼

#include<iostream>
#include<cstring>
#include<algorithm>
#include
<cstdio> #include<cstdlib> #include<cmath> #define FOR(x,y,z) for(int x=y;x<=z;x++) #define ll long long using namespace std; int dp[100005][5][3]; //定義狀態 int c[100005][4]; int n; int ans; int main() { scanf("%d",&n); FOR(i,1,n) scanf("%d %d %d",&c[i][1],&c[i][2],&c[i][3]);//分別輸入高度為10,20,30的價值 FOR(i,2,n) {//2~n的dp過程 dp[i][1][1]=max(dp[i-1][2][0],dp[i-1][3][0])+c[i][1]; dp[i][2][1]=dp[i-1][3][0]+c[i][2]; dp[i][2][0]=dp[i-1][1][1]+c[i][2]; dp[i][3][0]=max(dp[i-1][1][1],dp[i-1][2][1])+c[i][3]; } //將1,n特判 ans=max(ans,dp[n][1][1]+c[1][2]); ans=max(ans,dp[n][1][1]+c[1][3]); ans=max(ans,dp[n][2][1]+c[1][3]); ans=max(ans,dp[n][2][0]+c[1][1]); ans=max(ans,dp[n][3][0]+c[1][2]); ans=max(ans,dp[n][3][0]+c[1][1]); printf("%d",ans); return 0; }

洛谷教主花園dp