洛谷P1133 教主的花園

題目描述

教主有着一個環形的花園,他想在花園周圍均勻地種上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;
} 
相關文章
相關標籤/搜索