教主有着一個環形的花園,他想在花園周圍均勻地種上n棵樹,可是教主花園的土壤很特別,每一個位置適合種的樹都不同,一些樹可能會由於不適合這個位置的土壤而損失觀賞價值。html
教主最喜歡3種樹,這3種樹的高度分別爲10,20,30。教主但願這一圈樹種得有層次感,因此任何一個位置的樹要比它相鄰的兩棵樹的高度都高或者都低,而且在此條件下,教主想要你設計出一套方案,使得觀賞價值之和最高。ios
輸入格式:git
第一行爲一個正整數n,表示須要種的樹的棵樹。spa
接下來n行,每行3個不超過10000的正整數ai,bi,ci,按順時針順序表示了第ii個位置種高度爲10,20,30的樹能得到的觀賞價值。設計
第i個位置的樹與第i+1個位置的樹相鄰,特別地,第1個位置的樹與第n個位置的樹相鄰。code
輸出格式:htm
一個正整數,爲最大的觀賞價值和。blog
觀察全部種樹的狀態,無非四種:get
一、當前種矮樹,則前面可能種高的或者中的。string
二、當前爲中樹後面是矮樹,則前面必須是矮樹。
三、當前爲中樹後面是高樹,則前面必須是高樹。
四、當前是矮樹,則前面多是中樹或者矮樹。
而後根據這些條件,列出轉移方程。
對於處理環,只須要枚舉第一個位置種什麼樹就能夠了。
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #define in(a) a=read() #define REP(i,k,n) for(int i=k;i<=n;i++) using namespace std; inline int read(){ int x=0,f=1; char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1; for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; return x*f; } int n,ans; int inp[100010][3]; int dp[100010][4]; int main(){ in(n); REP(i,1,n) in(inp[i][0]),in(inp[i][1]),in(inp[i][2]); REP(t,0,3){ if(t==0) dp[1][0]=inp[1][0],dp[1][1]=-999999999,dp[1][2]=-999999999,dp[1][3]=-999999999; if(t==1) dp[1][1]=inp[1][1],dp[1][0]=-999999999,dp[1][2]=-999999999,dp[1][3]=-999999999; if(t==2) dp[1][2]=inp[1][1],dp[1][0]=-999999999,dp[1][1]=-999999999,dp[1][3]=-999999999; if(t==3) dp[1][3]=inp[1][2],dp[1][1]=-999999999,dp[1][2]=-999999999,dp[1][0]=-999999999; REP(i,2,n){ dp[i][0]=max(dp[i-1][2],dp[i-1][3])+inp[i][0]; dp[i][1]=dp[i-1][3]+inp[i][1]; dp[i][2]=dp[i-1][0]+inp[i][1]; dp[i][3]=max(dp[i-1][0],dp[i-1][1])+inp[i][2]; } if(t==0) ans=max(ans,max(dp[n][2],dp[n][3])); if(t==1) ans=max(ans,dp[n][3]); if(t==2) ans=max(ans,dp[n][0]); if(t==3) ans=max(ans,max(dp[n][0],dp[n][1])); } cout<<ans; return 0; }