$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且高度比相邻的矮的,那么第i-1棵肯定是高度为30且比相邻的两棵高的
dp[i][2][1]=dp[i-1][1][0]+b[i];
//种高度为20且高度比相邻的高的,那么第i-1棵肯定是高度为10且比相邻的两棵矮的
dp[i][3][1]=max(dp[i-1][1][0],dp[i-1][2][0])+c[i];
//种高度为30的树,肯定比相邻的两棵树高
取dp[n][1][0]、dp[n][2][0]、dp[n][2][1]、dp[n][3][1]的最大值
但是只有70分...
特别地,第1个位置的树与第n个位置的树相邻。
这个好像没有考虑过
所以要把位置为1的特殊处理
dp[1][1][0]=max(dp[n][2][1],dp[n][3][1])+a[1];
dp[1][2][0]=dp[n][3][1]+b[1];
dp[1][2][1]=dp[n][1][0]+b[1];
dp[1][3][1]=max(dp[n][1][0],dp[n][2][0])+c[1];
那么答案就应该是这个:
取dp[1][1][0]、dp[1][2][0]、dp[1][2][1]、dp[1][3][1]的最大值
完整代码:
#include<bits/stdc++.h>
using namespace std;
const int MAXN=100000+10;
int n;
int a[MAXN],b[MAXN],c[MAXN];
int dp[MAXN][4][2];
inline int read()
{
    int tot=0;
    char c=getchar();
    while(c<'0'||c>'9')
        c=getchar();
    while(c>='0'&&c<='9')
    {
        tot=tot*10+c-'0';
        c=getchar();
    }
    return tot;
}
int main()
{
    n=read();
    for(int i=1;i<=n;i++)
        a[i]=read(),b[i]=read(),c[i]=read();
    for(int i=2;i<=n;i++)
    {
        dp[i][1][0]=max(dp[i-1][2][1],dp[i-1][3][1])+a[i];
        dp[i][2][0]=dp[i-1][3][1]+b[i];
        dp[i][2][1]=dp[i-1][1][0]+b[i];
        dp[i][3][1]=max(dp[i-1][1][0],dp[i-1][2][0])+c[i];
    }
    dp[1][1][0]=max(dp[n][2][1],dp[n][3][1])+a[1];
    dp[1][2][0]=dp[n][3][1]+b[1];
    dp[1][2][1]=dp[n][1][0]+b[1];
    dp[1][3][1]=max(dp[n][1][0],dp[n][2][0])+c[1];
    cout<<max(dp[1][1][0],max(dp[1][2][0],max(dp[1][2][1],dp[1][3][1])))<<endl;
    return 0;
}原文:https://www.cnblogs.com/hulean/p/10818987.html