1. 程式人生 > >洛谷 題解 P1133 【教主的花園】

洛谷 題解 P1133 【教主的花園】

代碼 etc ons c++ 是否 處理 表示 esp 題解

$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;
}

洛谷 題解 P1133 【教主的花園】